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 <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")
00086
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
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
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
00229 if (!dynamically_loaded)
00230 cupsSetPasswordCB(getPassword);
00231
00232
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
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
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");
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 {
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
00300 newconf_.unknown_ = conf_->unknown_;
00301 if (!ok)
00302 {
00303 ;
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"