Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

userdialog.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  ***************************************************************************/
00009 
00010 #include "userdialog.h"
00011 #include "passwd.h"
00012 
00013 /* OPIE */
00014 #include <opie2/odebug.h>
00015 #include <opie2/odevice.h>
00016 #include <opie2/oresource.h>
00017 #include <qpe/qpeapplication.h>
00018 using namespace Opie::Core;
00019 using namespace Opie::Ui;
00020 
00021 /* QT */
00022 #include <qlayout.h>
00023 #include <qlabel.h>
00024 #include <qmessagebox.h>
00025 #include <qfile.h>
00026 
00027 /* STD */
00028 #include <sys/types.h>
00029 #include <sys/wait.h>
00030 #include <unistd.h>
00031 #include <signal.h>
00032 
00037 UserDialog::UserDialog(int viewmode, QWidget* parent, const char* name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl)
00038 {
00039     vm=viewmode;
00040     QVBoxLayout *layout = new QVBoxLayout(this);
00041     myTabWidget=new QTabWidget(this,"User Tab Widget");
00042     layout->addWidget(myTabWidget);
00043     setupTab1();
00044     setupTab2();
00045 
00046     accounts->groupStringList.sort();
00047     // And also fill the listview & the combobox with all available groups.
00048     for( QStringList::Iterator it = accounts->groupStringList.begin(); it!=accounts->groupStringList.end(); ++it)
00049     {
00050         accounts->splitGroupEntry(*it);
00051         if(accounts->gr_name.find(QRegExp("^#"),0))
00052         {    // Skip commented lines.
00053             new QCheckListItem(groupsListView,accounts->gr_name,QCheckListItem::CheckBox);
00054             groupComboBox->insertItem(accounts->gr_name);
00055         }
00056     }
00057     QPEApplication::showDialog( this );
00058 }
00059 
00064 UserDialog::~UserDialog()
00065 {}
00066 
00071 void UserDialog::setupTab1()
00072 {
00073     QPixmap mypixmap;
00074     QWidget *tabpage = new QWidget(myTabWidget,"page1");
00075     QVBoxLayout *layout = new QVBoxLayout(tabpage);
00076     layout->setMargin(5);
00077 
00078     // Picture
00079     picturePushButton = new QPushButton(tabpage,"Label");
00080     picturePushButton->setMinimumSize(48,48);
00081     picturePushButton->setMaximumSize(48,48);
00082     picturePushButton->setPixmap(Opie::Core::OResource::loadPixmap("usermanager/usericon"));    // Load default usericon.
00083     connect(picturePushButton,SIGNAL(clicked()),this,SLOT(clickedPicture()));    // Clicking the picture should invoke pictureselector.
00084 
00085     // Login
00086     QLabel *loginLabel=new QLabel(tabpage,"Login: ");
00087     loginLabel->setText("Login: ");
00088     loginLineEdit=new QLineEdit(tabpage,"Login: ");
00089 
00090     // UID
00091     QLabel *uidLabel=new QLabel(tabpage,"uid: ");
00092     uidLabel->setText("UserID: ");
00093     uidLineEdit=new QLineEdit(tabpage,"uid: ");
00094     uidLineEdit->setEnabled(false);
00095 
00096     // Username (gecos)
00097     QLabel *gecosLabel=new QLabel(tabpage,"gecos");
00098     gecosLabel->setText("Username: ");
00099     gecosLineEdit=new QLineEdit(tabpage,"gecos");
00100 
00101     // Password
00102     QLabel *passwordLabel=new QLabel(tabpage,"password");
00103     passwordLabel->setText("Password: ");
00104     passwordLineEdit=new QLineEdit(tabpage,"password");
00105     passwordLineEdit->setEchoMode(QLineEdit::Password);
00106 
00107     // Shell
00108     QLabel *shellLabel=new QLabel(tabpage,"shell");
00109     shellLabel->setText("Shell: ");
00110     shellComboBox=new QComboBox(tabpage,"shell");
00111     shellComboBox->setEditable(true);
00112     shellComboBox->insertItem("/bin/sh");
00113     shellComboBox->insertItem("/bin/ash");
00114     shellComboBox->insertItem("/bin/false");
00115 
00116     // Primary Group
00117     QLabel *groupLabel=new QLabel(tabpage,"group");
00118     groupLabel->setText("Primary group: ");
00119     groupComboBox=new QComboBox(tabpage,"PrimaryGroup");
00120 
00121     if(vm==VIEWMODE_NEW)
00122     {
00123         // Copy /etc/skel
00124         skelLabel=new QLabel(tabpage,"skel");
00125         skelLabel->setText("Copy /etc/skel: ");
00126         skelCheckBox=new QCheckBox(tabpage);
00127         skelCheckBox->setChecked(true);
00128     }
00129 
00130     // Widget layout
00131     QHBoxLayout *hlayout=new QHBoxLayout(-1,"hlayout");
00132     layout->addWidget(picturePushButton);
00133     layout->addSpacing(5);
00134     layout->addLayout(hlayout);
00135     QVBoxLayout *vlayout1=new QVBoxLayout(-1,"vlayout1");
00136     QVBoxLayout *vlayout2=new QVBoxLayout(-1,"vlayout2");
00137     // First column, labels
00138     vlayout1->addWidget(loginLabel);
00139     vlayout1->addSpacing(5);
00140     vlayout1->addWidget(uidLabel);
00141     vlayout1->addSpacing(5);
00142     vlayout1->addWidget(gecosLabel);
00143     vlayout1->addSpacing(5);
00144     vlayout1->addWidget(passwordLabel);
00145     vlayout1->addSpacing(5);
00146     vlayout1->addWidget(shellLabel);
00147     vlayout1->addSpacing(5);
00148     vlayout1->addWidget(groupLabel);
00149     if(vm==VIEWMODE_NEW)
00150     {
00151         vlayout1->addSpacing(5);
00152         vlayout1->addWidget(skelLabel);
00153     }
00154     // Second column, data
00155     vlayout2->addWidget(loginLineEdit);
00156     vlayout2->addSpacing(5);
00157     vlayout2->addWidget(uidLineEdit);
00158     vlayout2->addSpacing(5);
00159     vlayout2->addWidget(gecosLineEdit);
00160     vlayout2->addSpacing(5);
00161     vlayout2->addWidget(passwordLineEdit);
00162     vlayout2->addSpacing(5);
00163     vlayout2->addWidget(shellComboBox);
00164     vlayout2->addSpacing(5);
00165     vlayout2->addWidget(groupComboBox);
00166     if(vm==VIEWMODE_NEW)
00167     {
00168         vlayout2->addSpacing(5);
00169         vlayout2->addWidget(skelCheckBox);
00170     }
00171     hlayout->addLayout(vlayout1);
00172     hlayout->addLayout(vlayout2);
00173 
00174     myTabWidget->addTab(tabpage,"User Info");
00175 }
00176 
00181 void UserDialog::setupTab2()
00182 {
00183     QWidget *tabpage = new QWidget(myTabWidget,"page2");
00184     QVBoxLayout *layout = new QVBoxLayout(tabpage);
00185     layout->setMargin(5);
00186 
00187     // Additional groups
00188     groupsListView=new QListView(tabpage,"groups");
00189     groupsListView->addColumn("Additional groups");
00190     groupsListView->setColumnWidthMode(0,QListView::Maximum);
00191     groupsListView->setMultiSelection(false);
00192     groupsListView->setAllColumnsShowFocus(false);
00193 
00194     layout->addSpacing(5);
00195     // Grouplist
00196     layout->addWidget(groupsListView);
00197 
00198     myTabWidget->addTab(tabpage,"User Groups");
00199 }
00200 
00211 bool UserDialog::addUser(int uid, int gid)
00212 {
00213     QCheckListItem *temp;
00214     QFile ozTest;
00215     int oz=false;
00216     if(ODevice::inst()->system()==System_OpenZaurus) oz=true;
00217     // viewmode is a workaround for a bug in qte-2.3.4 that gives bus error on manipulating adduserDialog's widgets here.
00218     UserDialog *adduserDialog=new UserDialog(VIEWMODE_NEW);
00219     adduserDialog->setCaption(tr("Add User"));
00220     adduserDialog->userID=uid;    // Set next available UID as default uid.
00221     adduserDialog->groupID=gid;    // Set next available GID as default gid.
00222     // Insert default group into groupComboBox
00223     adduserDialog->groupComboBox->insertItem("<create new group>",0);
00224     adduserDialog->uidLineEdit->setText(QString::number(uid));
00225     // If we're running on OZ, add new users to some default groups.
00226     if(oz)
00227     {
00228         QListViewItemIterator iter( adduserDialog->groupsListView );
00229         for ( ; iter.current(); ++iter )
00230         {
00231             temp=(QCheckListItem*)iter.current();
00232             if (temp->text()=="video") temp->setOn(true);
00233             if (temp->text()=="audio") temp->setOn(true);
00234             if (temp->text()=="time") temp->setOn(true);
00235             if (temp->text()=="power") temp->setOn(true);
00236             if (temp->text()=="input") temp->setOn(true);
00237             if (temp->text()=="sharp") temp->setOn(true);
00238             if (temp->text()=="tty") temp->setOn(true);
00239         }
00240     }
00241     // Show the dialog!
00242     if(!(adduserDialog->exec())) return false;
00243     if((adduserDialog->groupComboBox->currentItem()!=0))
00244     {
00245         accounts->findGroup(adduserDialog->groupComboBox->currentText());
00246         adduserDialog->groupID=accounts->gr_gid;
00247         owarn << QString::number(accounts->gr_gid) << oendl; 
00248     }
00249     if(!(accounts->addUser(adduserDialog->loginLineEdit->text(), adduserDialog->passwordLineEdit->text(),
00250                            adduserDialog->uidLineEdit->text().toInt(), adduserDialog->groupID, adduserDialog->gecosLineEdit->text(),
00251                            QString("/home/")+adduserDialog->loginLineEdit->text() , adduserDialog->shellComboBox->currentText())))
00252     {
00253         QMessageBox::information(0,"Ooops!","Something went wrong!\nUnable to add user.");
00254         return false;
00255     }
00256 
00257     // Add User to additional groups.
00258     QListViewItemIterator it( adduserDialog->groupsListView );
00259     for ( ; it.current(); ++it )
00260     {
00261         temp=(QCheckListItem*)it.current();
00262         if (temp->isOn() )
00263             accounts->addGroupMember(it.current()->text(0),adduserDialog->loginLineEdit->text());
00264     }
00265     // Copy image to pics/users/
00266     if(!(adduserDialog->userImage.isNull()))
00267     {
00268         QDir d;
00269         if(!(d.exists(QPEApplication::qpeDir() + "pics/users")))
00270         {
00271             d.mkdir(QPEApplication::qpeDir() + "pics/users");
00272         }
00273         QString filename= QPEApplication::qpeDir()+"pics/users/"+accounts->pw_name+".png";
00274         //        adduserDialog->userImage=adduserDialog->userImage.smoothScale(48,48);
00275         adduserDialog->userImage.save(filename,"PNG");
00276     }
00277 
00278     // Should we copy the skeleton homedirectory /etc/skel to the user's homedirectory?
00279     accounts->findUser(adduserDialog->loginLineEdit->text());
00280     if(adduserDialog->skelCheckBox->isChecked())
00281     {
00282         QString command_cp;
00283         QString command_chown;
00284         command_cp.sprintf("cp -a /etc/skel/* %s/",accounts->pw_dir.latin1());
00285         system(command_cp);
00286 
00287         command_cp.sprintf("cp -a /etc/skel/.[!.]* %s/",accounts->pw_dir.latin1());    // Bug in busybox, ".*" includes parent directory, does this work as a workaround?
00288         system(command_cp);
00289 
00290         command_chown.sprintf("chown -R %d:%d %s",accounts->pw_uid,accounts->pw_gid,accounts->pw_dir.latin1());
00291         system(command_chown);
00292     }
00293 
00294     return true;
00295 }
00296 
00305 bool UserDialog::delUser(const char *username)
00306 {
00307     if((accounts->findUser(username)))
00308     {    // Does that user exist?
00309         if(!(accounts->delUser(username)))
00310         {    // Delete the user.
00311             QMessageBox::information(0,"Ooops!","Something went wrong\nUnable to delete user: "+QString(username)+".");
00312         }
00313     }
00314     else
00315     {
00316         QMessageBox::information(0,"Invalid Username","That username ("+QString(username)+")does not exist.");
00317         return false;
00318     }
00319     return true;
00320 }
00321 
00331 bool UserDialog::editUser(const char *username)
00332 {
00333     int invalid_group=0;
00334     // viewmode is a workaround for a bug in qte-2.3.4 that gives bus error on manipulating edituserDialog's widgets here.
00335     UserDialog *edituserDialog=new UserDialog(VIEWMODE_EDIT);    // Create Dialog
00336     edituserDialog->setCaption(tr("Edit User"));
00337     accounts->findUser(username);    // Locate user in database and fill variables in 'accounts' object.
00338     if(!(accounts->findGroup(accounts->pw_gid)))
00339     {    // Locate the user's primary group, and fill group variables in 'accounts' object.
00340         invalid_group=1;
00341     }
00342     // Fill widgets with userinfo.
00343     edituserDialog->loginLineEdit->setText(accounts->pw_name);
00344     edituserDialog->uidLineEdit->setText(QString::number(accounts->pw_uid));
00345     edituserDialog->gecosLineEdit->setText(accounts->pw_gecos);
00346     // Set password to '........', we will later check if this still is the contents, if not, the password has been changed.
00347     edituserDialog->passwordLineEdit->setText("........");
00348     // If this user is not using /bin/sh,/bin/ash or /bin/false as shell, add that entry to the shell-combobox.
00349     if(accounts->pw_shell!="/bin/sh" && accounts->pw_shell!="/bin/ash" && accounts->pw_shell!="/bin/false")
00350     {
00351         edituserDialog->shellComboBox->insertItem(accounts->pw_shell,0);
00352         edituserDialog->shellComboBox->setCurrentItem(0);
00353     }
00354     // Select the primary group for this user.
00355     for(int i=0;i<edituserDialog->groupComboBox->count();++i)
00356     {
00357         if(accounts->gr_name==edituserDialog->groupComboBox->text(i))
00358         {
00359             edituserDialog->groupComboBox->setCurrentItem(i);
00360             break;
00361         }
00362     }
00363     if(invalid_group)
00364     {
00365         edituserDialog->groupComboBox->insertItem("<Undefined group>",0);
00366         edituserDialog->groupComboBox->setCurrentItem(0);
00367     }
00368 
00369     // Select the groups in the listview, to which the user belongs.
00370     QCheckListItem *temp;
00371     // BAH!!! QRegExp in qt2 sucks... or maybe I do... can't figure out how to check for EITHER end of input ($) OR a comma, so here we do two different QRegExps instead.
00372     QRegExp userRegExp(QString("[:,]%1$").arg(username));    // The end of line variant.
00373     QStringList tempList=accounts->groupStringList.grep(userRegExp);    // Find all entries in the group database, that the user is a member of.
00374     for(QStringList::Iterator it=tempList.begin(); it!=tempList.end(); ++it)
00375     {    // Iterate over all of them.
00376         owarn << *it << oendl; 
00377         QListViewItemIterator lvit( edituserDialog->groupsListView );    // Compare to all groups.
00378         for ( ; lvit.current(); ++lvit )
00379         {
00380             if(lvit.current()->text(0)==(*it).left((*it).find(":")))
00381             {
00382                 temp=(QCheckListItem*)lvit.current();
00383                 temp->setOn(true);    // If we find a line with that groupname, select it.;
00384             }
00385         }
00386     }
00387     userRegExp=QRegExp(QString("[:,]%1,").arg(username));    // And the other one. (not end of line.)
00388     tempList=accounts->groupStringList.grep(userRegExp);    // Find all entries in the group database, that the user is a member of.
00389     for(QStringList::Iterator it=tempList.begin(); it!=tempList.end(); ++it)
00390     {    // Iterate over all of them.
00391         owarn << *it << oendl; 
00392         QListViewItemIterator lvit( edituserDialog->groupsListView );    // Compare to all groups.
00393         for ( ; lvit.current(); ++lvit )
00394         {
00395             if(lvit.current()->text(0)==(*it).left((*it).find(":")))
00396             {
00397                 temp=(QCheckListItem*)lvit.current();
00398                 temp->setOn(true);    // If we find a line with that groupname, select it.;
00399             }
00400         }
00401     }
00402 
00403     if(!(edituserDialog->exec())) return false;    // SHOW THE DIALOG!
00404 
00405     accounts->findUser(username);    // Fill user variables in 'acccounts' object.
00406     accounts->pw_name=edituserDialog->loginLineEdit->text();
00407     // Has the password been changed ? Make a new "crypt":ed password.
00408     if(edituserDialog->passwordLineEdit->text()!="........") accounts->pw_passwd=crypt(edituserDialog->passwordLineEdit->text(), accounts->crypt_make_salt());
00409 
00410     // Set all variables in accounts object, that will be used when calling 'updateUser()'
00411     accounts->pw_uid=edituserDialog->uidLineEdit->text().toInt();
00412     if(accounts->findGroup(edituserDialog->groupComboBox->currentText()))
00413     {    // Fill all group variables in 'accounts' object.
00414         accounts->pw_gid=accounts->gr_gid;    // Only do this if the group is a valid group (ie. "<Undefined group>"), otherwise keep the old group.
00415     }
00416     accounts->pw_gecos=edituserDialog->gecosLineEdit->text();
00417     accounts->pw_shell=edituserDialog->shellComboBox->currentText();
00418     // Update userinfo, using the information stored in the user variables stored in the accounts object.
00419     accounts->updateUser(username);
00420 
00421     // Remove user from all groups he/she is a member of. (could be done in a better way I guess, this was simple though.)
00422     for(QStringList::Iterator it=tempList.begin(); it!=tempList.end(); ++it)
00423     {
00424         accounts->delGroupMember((*it).left((*it).find(":")),username);
00425     }
00426 
00427     // Add User to additional groups that he/she is a member of.
00428     QListViewItemIterator it( edituserDialog->groupsListView );
00429     for ( ; it.current(); ++it )
00430     {
00431         temp=(QCheckListItem*)it.current();
00432         if ( temp->isOn() )
00433             accounts->addGroupMember(it.current()->text(0),edituserDialog->loginLineEdit->text());
00434     }
00435 
00436     // Copy image to pics/users/
00437     if(!(edituserDialog->userImage.isNull()))
00438     {
00439         QDir d;
00440         if(!(d.exists(QPEApplication::qpeDir()+"pics/users")))
00441         {
00442             d.mkdir(QPEApplication::qpeDir()+"pics/users");
00443         }
00444         QString filename=QPEApplication::qpeDir()+"pics/users/"+accounts->pw_name+".png";
00445         //        edituserDialog->userImage=edituserDialog->userImage.smoothScale(48,48);
00446         edituserDialog->userImage.save(filename,"PNG");
00447     }
00448     return true;
00449 }
00450 
00455 void UserDialog::accept()
00456 {
00457     // Add checking... valid username? username taken?
00458     if(loginLineEdit->text().isEmpty())
00459     {
00460         QMessageBox::information(0,"Empty Login","Please enter a login.");
00461         return;
00462     }
00463     QDialog::accept();
00464 }
00465 
00470 void UserDialog::clickedPicture()
00471 {
00472     QString filename=OFileDialog::getOpenFileName(OFileSelector::EXTENDED, QString::null);
00473     if(!(filename.isEmpty()))
00474     {
00475         userImage.reset();
00476         if(!(userImage.load(filename)))
00477         {
00478             QMessageBox::information(0,"Sorry!","That icon could not be loaded.\nLoading failed on: "+filename);
00479         }
00480         else
00481         {
00482             //            userImage=userImage.smoothScale(48,48);
00483             QPixmap *picture;
00484             picture=(QPixmap *)picturePushButton->pixmap();
00485             picture->convertFromImage(userImage,0);
00486             picturePushButton->update();
00487         }
00488     }
00489 }

Generated on Sat Nov 5 16:17:58 2005 for OPIE by  doxygen 1.4.2