00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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")
00085
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
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
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
00225 if (!dynamically_loaded)
00226 cupsSetPasswordCB(getPassword);
00227
00228
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
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
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");
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 {
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
00296 newconf_.unknown_ = conf_->unknown_;
00297 if (!ok)
00298 {
00299 ;
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"