kdeprint Library API Documentation

/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., 59 Temple Place - Suite 330,
00017  *  Boston, MA 02111-1307, 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 <stdlib.h>
00049 #include <signal.h>
00050 #include <cups/cups.h>
00051 
00052 static bool dynamically_loaded = false;
00053 static QString  pass_string;
00054 
00055 extern "C"
00056 {
00057 #include "cups-util.h"
00058     KDEPRINT_EXPORT bool restartServer(QString& msg)
00059     {
00060         return CupsdDialog::restartServer(msg);
00061     }
00062     KDEPRINT_EXPORT bool configureServer(QWidget *parent, QString& msg)
00063     {
00064         dynamically_loaded = true;
00065         bool result = CupsdDialog::configure(QString::null, parent, &msg);
00066         dynamically_loaded = false;
00067         return result;
00068     }
00069 }
00070 
00071 int getServerPid()
00072 {
00073     QDir    dir("/proc",QString::null,QDir::Name,QDir::Dirs);
00074     for (uint i=0;i<dir.count();i++)
00075     {
00076         if (dir[i] == "." || dir[i] == ".." || dir[i] == "self") continue;
00077         QFile   f("/proc/" + dir[i] + "/cmdline");
00078         if (f.exists() && f.open(IO_ReadOnly))
00079         {
00080             QTextStream t(&f);
00081             QString line;
00082             t >> line;
00083             f.close();
00084             if (line.right(5) == "cupsd" ||
00085                 line.right(6).left(5) == "cupsd")   // second condition for 2.4.x kernels
00086                                 // which add a null byte at the end
00087                 return dir[i].toInt();
00088         }
00089     }
00090     return (-1);
00091 }
00092 
00093 const char* getPassword(const char*)
00094 {
00095     QString user(cupsUser());
00096     QString pass;
00097 
00098     if (KIO::PasswordDialog::getNameAndPassword(user, pass, NULL) == QDialog::Accepted)
00099     {
00100         cupsSetUser(user.latin1());
00101         pass_string = pass;
00102         if (pass_string.isEmpty())
00103             return "";
00104         else
00105             return pass_string.latin1();
00106     }
00107     else
00108         return NULL;
00109 }
00110 
00111 //---------------------------------------------------
00112 
00113 CupsdDialog::CupsdDialog(QWidget *parent, const char *name)
00114     : KDialogBase(IconList, "", Ok|Cancel|User1, Ok, parent, name, true, true, KGuiItem(i18n("Short Help"), "help"))
00115 {
00116     KGlobal::iconLoader()->addAppDir("kdeprint");
00117     KGlobal::locale()->insertCatalogue("cupsdconf");
00118 
00119     setShowIconsInTreeList(true);
00120     setRootIsDecorated(false);
00121 
00122     pagelist_.setAutoDelete(false);
00123     filename_ = "";
00124     conf_ = 0;
00125     constructDialog();
00126 
00127         setCaption(i18n("CUPS Server Configuration"));
00128 
00129         //resize(500, 400);
00130 }
00131 
00132 CupsdDialog::~CupsdDialog()
00133 {
00134         delete conf_;
00135 }
00136 
00137 void CupsdDialog::addConfPage(CupsdPage *page)
00138 {
00139     QPixmap icon = KGlobal::instance()->iconLoader()->loadIcon(
00140                                                                page->pixmap(),
00141                                                                    KIcon::NoGroup,
00142                                                                    KIcon::SizeMedium
00143                                                               );
00144 
00145     QVBox   *box = addVBoxPage(page->pageLabel(), page->header(), icon);
00146     page->reparent(box, QPoint(0,0));
00147     pagelist_.append(page);
00148 }
00149 
00150 void CupsdDialog::constructDialog()
00151 {
00152     addConfPage(new CupsdSplash(0));
00153     addConfPage(new CupsdServerPage(0));
00154     addConfPage(new CupsdNetworkPage(0));
00155     addConfPage(new CupsdSecurityPage(0));
00156     addConfPage(new CupsdLogPage(0));
00157     addConfPage(new CupsdJobsPage(0));
00158     addConfPage(new CupsdFilterPage(0));
00159     addConfPage(new CupsdDirPage(0));
00160     addConfPage(new CupsdBrowsingPage(0));
00161 
00162     conf_ = new CupsdConf();
00163     for (pagelist_.first();pagelist_.current();pagelist_.next())
00164         {
00165                 pagelist_.current()->setInfos(conf_);
00166         }
00167 }
00168 
00169 bool CupsdDialog::setConfigFile(const QString& filename)
00170 {
00171     filename_ = filename;
00172     if (!conf_->loadFromFile(filename_))
00173     {
00174         KMessageBox::error(this, i18n("Error while loading configuration file!"), i18n("CUPS Configuration Error"));
00175         return false;
00176     }
00177     if (conf_->unknown_.count() > 0)
00178     {
00179         // there were some unknown options, warn the user
00180         QString msg;
00181         for (QValueList< QPair<QString,QString> >::ConstIterator it=conf_->unknown_.begin(); it!=conf_->unknown_.end(); ++it)
00182             msg += ((*it).first + " = " + (*it).second + "<br>");
00183         msg.prepend("<p>" + i18n("Some options were not recognized by this configuration tool. "
00184                                   "They will be left untouched and you won't be able to change them.") + "</p>");
00185         KMessageBox::sorry(this, msg, i18n("Unrecognized Options"));
00186     }
00187     bool    ok(true);
00188     QString msg;
00189     for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00190         ok = pagelist_.current()->loadConfig(conf_, msg);
00191     if (!ok)
00192     {
00193         KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00194         return false;
00195     }
00196     return true;
00197 }
00198 
00199 bool CupsdDialog::restartServer(QString& msg)
00200 {
00201     int serverPid = getServerPid();
00202         msg.truncate(0);
00203     if (serverPid <= 0)
00204     {
00205         msg = i18n("Unable to find a running CUPS server");
00206     }
00207     else
00208     {
00209         KProcess proc;
00210                 bool success = false;
00211                 if (getuid() == 0 )
00212                         proc << "rccups" << "force-reload";
00213                 else
00214                         proc << "kdesu" << "-c" << "rccups" << "force-reload";
00215         success = proc.start( KProcess::Block ) && proc.normalExit();
00216                 if( !success )    
00217             msg = i18n("Unable to restart CUPS server (pid = %1)").arg(serverPid);
00218     }
00219         return (msg.isEmpty());
00220 }
00221 
00222 bool CupsdDialog::configure(const QString& filename, QWidget *parent, QString *msg)
00223 {
00224     bool needUpload(false);
00225     QString errormsg;
00226     bool result = true;
00227 
00228     // init password dialog if needed
00229     if (!dynamically_loaded)
00230         cupsSetPasswordCB(getPassword);
00231 
00232     // load config file from server
00233     QString fn(filename);
00234     if (fn.isEmpty())
00235     {
00236         fn = cupsGetConf();
00237         if (fn.isEmpty())
00238             errormsg = i18n("Unable to retrieve configuration file from the CUPS server. "
00239                         "You probably don't have the access permissions to perform this operation.");
00240         else needUpload = true;
00241     }
00242 
00243     // check read state (only if needed)
00244     if (!fn.isEmpty())
00245     {
00246         QFileInfo   fi(fn);
00247         if (!fi.exists() || !fi.isReadable() || !fi.isWritable())
00248             errormsg = i18n("Internal error: file '%1' not readable/writable!").arg(fn);
00249         // check file size
00250         if (fi.size() == 0)
00251             errormsg = i18n("Internal error: empty file '%1'!").arg(fn);
00252     }
00253 
00254     if (!errormsg.isEmpty())
00255     {
00256         if ( !dynamically_loaded )
00257             KMessageBox::error(parent, errormsg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00258         result = false;
00259     }
00260     else
00261     {
00262         KGlobal::locale()->insertCatalogue("cupsdconf"); // Must be before dialog is created to translate "Short Help"
00263         CupsdDialog dlg(parent);
00264         if (dlg.setConfigFile(fn) && dlg.exec())
00265         {
00266             QCString    encodedFn = QFile::encodeName(fn);
00267             if (!needUpload)
00268                 KMessageBox::information(parent,
00269                     i18n("The config file has not been uploaded to the "
00270                          "CUPS server. The daemon will not be restarted."));
00271             else if (!cupsPutConf(encodedFn.data()))
00272             {
00273                 errormsg = i18n("Unable to upload the configuration file to CUPS server. "
00274                          "You probably don't have the access permissions to perform this operation.");
00275                 if ( !dynamically_loaded )
00276                     KMessageBox::error(parent, errormsg, i18n("CUPS configuration error"));
00277                 result = false;
00278             }
00279         }
00280 
00281     }
00282     if (needUpload)
00283         QFile::remove(fn);
00284 
00285     if ( msg )
00286         *msg = errormsg;
00287     return result;
00288 }
00289 
00290 void CupsdDialog::slotOk()
00291 {
00292     if (conf_ && !filename_.isEmpty())
00293     { // try to save the file
00294         bool    ok(true);
00295         QString msg;
00296         CupsdConf   newconf_;
00297         for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00298             ok = pagelist_.current()->saveConfig(&newconf_, msg);
00299         // copy unknown options
00300         newconf_.unknown_ = conf_->unknown_;
00301         if (!ok)
00302         {
00303             ; // do nothing
00304         }
00305         else if (!newconf_.saveToFile(filename_))
00306         {
00307             msg = i18n("Unable to write configuration file %1").arg(filename_);
00308                 ok = false;
00309         }
00310         if (!ok)
00311         {
00312             KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00313         }
00314         else
00315             KDialogBase::slotOk();
00316     }
00317 }
00318 
00319 void CupsdDialog::slotUser1()
00320 {
00321     QWhatsThis::enterWhatsThisMode();
00322 }
00323 
00324 int CupsdDialog::serverPid()
00325 {
00326     return getServerPid();
00327 }
00328 
00329 int CupsdDialog::serverOwner()
00330 {
00331     int pid = getServerPid();
00332     if (pid > 0)
00333     {
00334         QString str;
00335         str.sprintf("/proc/%d/status",pid);
00336         QFile   f(str);
00337         if (f.exists() && f.open(IO_ReadOnly))
00338         {
00339             QTextStream t(&f);
00340             while (!t.eof())
00341             {
00342                 str = t.readLine();
00343                 if (str.find("Uid:",0,false) == 0)
00344                 {
00345                     QStringList list = QStringList::split('\t', str, false);
00346                     if (list.count() >= 2)
00347                     {
00348                         bool    ok;
00349                         int u = list[1].toInt(&ok);
00350                         if (ok) return u;
00351                     }
00352                 }
00353             }
00354         }
00355     }
00356     return (-1);
00357 }
00358 
00359 #include "cupsddialog.moc"
KDE Logo
This file is part of the documentation for kdeprint Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Mar 22 19:53:23 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003