cupsddialog.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License version 2 as published by the Free Software Foundation.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Library General Public License
00015  *  along with this library; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
00018  **/
00019 
00020 #include "cupsddialog.h"
00021 
00022 #include "cupsdpage.h"
00023 #include "cupsdconf.h"
00024 #include "cupsdsplash.h"
00025 #include "cupsdserverpage.h"
00026 #include "cupsdlogpage.h"
00027 #include "cupsdjobspage.h"
00028 #include "cupsdfilterpage.h"
00029 #include "cupsddirpage.h"
00030 #include "cupsdnetworkpage.h"
00031 #include "cupsdbrowsingpage.h"
00032 #include "cupsdsecuritypage.h"
00033 
00034 #include <qdir.h>
00035 #include <qvbox.h>
00036 #include <kmessagebox.h>
00037 #include <klocale.h>
00038 #include <qfile.h>
00039 #include <qfileinfo.h>
00040 #include <kglobal.h>
00041 #include <kiconloader.h>
00042 #include <qstringlist.h>
00043 #include <qwhatsthis.h>
00044 #include <kio/passdlg.h>
00045 #include <kguiitem.h>
00046 #include <kprocess.h>
00047 
00048 #include <signal.h>
00049 #include <cups/cups.h>
00050 
00051 static bool dynamically_loaded = false;
00052 static QString  pass_string;
00053 
00054 extern "C"
00055 {
00056 #include "cups-util.h"
00057     KDEPRINT_EXPORT bool restartServer(QString& msg)
00058     {
00059         return CupsdDialog::restartServer(msg);
00060     }
00061     KDEPRINT_EXPORT bool configureServer(QWidget *parent, QString& msg)
00062     {
00063         dynamically_loaded = true;
00064         bool result = CupsdDialog::configure(QString::null, parent, &msg);
00065         dynamically_loaded = false;
00066         return result;
00067     }
00068 }
00069 
00070 int getServerPid()
00071 {
00072     QDir    dir("/proc",QString::null,QDir::Name,QDir::Dirs);
00073     for (uint i=0;i<dir.count();i++)
00074     {
00075         if (dir[i] == "." || dir[i] == ".." || dir[i] == "self") continue;
00076         QFile   f("/proc/" + dir[i] + "/cmdline");
00077         if (f.exists() && f.open(IO_ReadOnly))
00078         {
00079             QTextStream t(&f);
00080             QString line;
00081             t >> line;
00082             f.close();
00083             if (line.right(5) == "cupsd" ||
00084                 line.right(6).left(5) == "cupsd")   // second condition for 2.4.x kernels
00085                                 // which add a null byte at the end
00086                 return dir[i].toInt();
00087         }
00088     }
00089     return (-1);
00090 }
00091 
00092 const char* getPassword(const char*)
00093 {
00094     QString user(cupsUser());
00095     QString pass;
00096 
00097     if (KIO::PasswordDialog::getNameAndPassword(user, pass, NULL) == QDialog::Accepted)
00098     {
00099         cupsSetUser(user.latin1());
00100         pass_string = pass;
00101         if (pass_string.isEmpty())
00102             return "";
00103         else
00104             return pass_string.latin1();
00105     }
00106     else
00107         return NULL;
00108 }
00109 
00110 //---------------------------------------------------
00111 
00112 CupsdDialog::CupsdDialog(QWidget *parent, const char *name)
00113     : KDialogBase(IconList, "", Ok|Cancel|User1, Ok, parent, name, true, true, KGuiItem(i18n("Short Help"), "help"))
00114 {
00115     KGlobal::iconLoader()->addAppDir("kdeprint");
00116     KGlobal::locale()->insertCatalogue("cupsdconf");
00117 
00118     setShowIconsInTreeList(true);
00119     setRootIsDecorated(false);
00120 
00121     pagelist_.setAutoDelete(false);
00122     filename_ = "";
00123     conf_ = 0;
00124     constructDialog();
00125 
00126         setCaption(i18n("CUPS Server Configuration"));
00127 
00128         //resize(500, 400);
00129 }
00130 
00131 CupsdDialog::~CupsdDialog()
00132 {
00133         delete conf_;
00134 }
00135 
00136 void CupsdDialog::addConfPage(CupsdPage *page)
00137 {
00138     QPixmap icon = KGlobal::instance()->iconLoader()->loadIcon(
00139                                                                page->pixmap(),
00140                                                                    KIcon::NoGroup,
00141                                                                    KIcon::SizeMedium
00142                                                               );
00143 
00144     QVBox   *box = addVBoxPage(page->pageLabel(), page->header(), icon);
00145     page->reparent(box, QPoint(0,0));
00146     pagelist_.append(page);
00147 }
00148 
00149 void CupsdDialog::constructDialog()
00150 {
00151     addConfPage(new CupsdSplash(0));
00152     addConfPage(new CupsdServerPage(0));
00153     addConfPage(new CupsdNetworkPage(0));
00154     addConfPage(new CupsdSecurityPage(0));
00155     addConfPage(new CupsdLogPage(0));
00156     addConfPage(new CupsdJobsPage(0));
00157     addConfPage(new CupsdFilterPage(0));
00158     addConfPage(new CupsdDirPage(0));
00159     addConfPage(new CupsdBrowsingPage(0));
00160 
00161     conf_ = new CupsdConf();
00162     for (pagelist_.first();pagelist_.current();pagelist_.next())
00163         {
00164                 pagelist_.current()->setInfos(conf_);
00165         }
00166 }
00167 
00168 bool CupsdDialog::setConfigFile(const QString& filename)
00169 {
00170     filename_ = filename;
00171     if (!conf_->loadFromFile(filename_))
00172     {
00173         KMessageBox::error(this, i18n("Error while loading configuration file!"), i18n("CUPS Configuration Error"));
00174         return false;
00175     }
00176     if (conf_->unknown_.count() > 0)
00177     {
00178         // there were some unknown options, warn the user
00179         QString msg;
00180         for (QValueList< QPair<QString,QString> >::ConstIterator it=conf_->unknown_.begin(); it!=conf_->unknown_.end(); ++it)
00181             msg += ((*it).first + " = " + (*it).second + "<br>");
00182         msg.prepend("<p>" + i18n("Some options were not recognized by this configuration tool. "
00183                                   "They will be left untouched and you won't be able to change them.") + "</p>");
00184         KMessageBox::sorry(this, msg, i18n("Unrecognized Options"));
00185     }
00186     bool    ok(true);
00187     QString msg;
00188     for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00189         ok = pagelist_.current()->loadConfig(conf_, msg);
00190     if (!ok)
00191     {
00192         KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00193         return false;
00194     }
00195     return true;
00196 }
00197 
00198 bool CupsdDialog::restartServer(QString& msg)
00199 {
00200     int serverPid = getServerPid();
00201         msg.truncate(0);
00202     if (serverPid <= 0)
00203     {
00204         msg = i18n("Unable to find a running CUPS server");
00205     }
00206     else
00207     {
00208                 bool success = false;
00209         KProcess proc;
00210         proc << "kdesu" << "-c" << "/etc/init.d/cupsys restart";
00211         success = proc.start( KProcess::Block ) && proc.normalExit();
00212                 if( !success )    
00213             msg = i18n("Unable to restart CUPS server (pid = %1)").arg(serverPid);
00214     }
00215         return (msg.isEmpty());
00216 }
00217 
00218 bool CupsdDialog::configure(const QString& filename, QWidget *parent, QString *msg)
00219 {
00220     bool needUpload(false);
00221     QString errormsg;
00222     bool result = true;
00223 
00224     // init password dialog if needed
00225     if (!dynamically_loaded)
00226         cupsSetPasswordCB(getPassword);
00227 
00228     // load config file from server
00229     QString fn(filename);
00230     if (fn.isEmpty())
00231     {
00232         fn = cupsGetConf();
00233         if (fn.isEmpty())
00234             errormsg = i18n("Unable to retrieve configuration file from the CUPS server. "
00235                         "You probably don't have the access permissions to perform this operation.");
00236         else needUpload = true;
00237     }
00238 
00239     // check read state (only if needed)
00240     if (!fn.isEmpty())
00241     {
00242         QFileInfo   fi(fn);
00243         if (!fi.exists() || !fi.isReadable() || !fi.isWritable())
00244             errormsg = i18n("Internal error: file '%1' not readable/writable!").arg(fn);
00245         // check file size
00246         if (fi.size() == 0)
00247             errormsg = i18n("Internal error: empty file '%1'!").arg(fn);
00248     }
00249 
00250     if (!errormsg.isEmpty())
00251     {
00252         if ( !dynamically_loaded )
00253             KMessageBox::error(parent, errormsg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00254         result = false;
00255     }
00256     else
00257     {
00258         KGlobal::locale()->insertCatalogue("cupsdconf"); // Must be before dialog is created to translate "Short Help"
00259         CupsdDialog dlg(parent);
00260         if (dlg.setConfigFile(fn) && dlg.exec())
00261         {
00262             QCString    encodedFn = QFile::encodeName(fn);
00263             if (!needUpload)
00264                 KMessageBox::information(parent,
00265                     i18n("The config file has not been uploaded to the "
00266                          "CUPS server. The daemon will not be restarted."));
00267             else if (!cupsPutConf(encodedFn.data()))
00268             {
00269                 errormsg = i18n("Unable to upload the configuration file to CUPS server. "
00270                          "You probably don't have the access permissions to perform this operation.");
00271                 if ( !dynamically_loaded )
00272                     KMessageBox::error(parent, errormsg, i18n("CUPS configuration error"));
00273                 result = false;
00274             }
00275         }
00276 
00277     }
00278     if (needUpload)
00279         QFile::remove(fn);
00280 
00281     if ( msg )
00282         *msg = errormsg;
00283     return result;
00284 }
00285 
00286 void CupsdDialog::slotOk()
00287 {
00288     if (conf_ && !filename_.isEmpty())
00289     { // try to save the file
00290         bool    ok(true);
00291         QString msg;
00292         CupsdConf   newconf_;
00293         for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00294             ok = pagelist_.current()->saveConfig(&newconf_, msg);
00295         // copy unknown options
00296         newconf_.unknown_ = conf_->unknown_;
00297         if (!ok)
00298         {
00299             ; // do nothing
00300         }
00301         else if (!newconf_.saveToFile(filename_))
00302         {
00303             msg = i18n("Unable to write configuration file %1").arg(filename_);
00304                 ok = false;
00305         }
00306         if (!ok)
00307         {
00308             KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00309         }
00310         else
00311             KDialogBase::slotOk();
00312     }
00313 }
00314 
00315 void CupsdDialog::slotUser1()
00316 {
00317     QWhatsThis::enterWhatsThisMode();
00318 }
00319 
00320 int CupsdDialog::serverPid()
00321 {
00322     return getServerPid();
00323 }
00324 
00325 int CupsdDialog::serverOwner()
00326 {
00327     int pid = getServerPid();
00328     if (pid > 0)
00329     {
00330         QString str;
00331         str.sprintf("/proc/%d/status",pid);
00332         QFile   f(str);
00333         if (f.exists() && f.open(IO_ReadOnly))
00334         {
00335             QTextStream t(&f);
00336             while (!t.eof())
00337             {
00338                 str = t.readLine();
00339                 if (str.find("Uid:",0,false) == 0)
00340                 {
00341                     QStringList list = QStringList::split('\t', str, false);
00342                     if (list.count() >= 2)
00343                     {
00344                         bool    ok;
00345                         int u = list[1].toInt(&ok);
00346                         if (ok) return u;
00347                     }
00348                 }
00349             }
00350         }
00351     }
00352     return (-1);
00353 }
00354 
00355 #include "cupsddialog.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys