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 if (getuid() == 0 )
00210 success = (::kill(serverPid, SIGHUP) == 0);
00211 else
00212 {
00213 KProcess proc;
00214 proc << "kdesu" << "-c" << "kill -SIGHUP " + QString::number( serverPid );
00215 success = proc.start( KProcess::Block ) && proc.normalExit();
00216 }
00217 if( !success )
00218 msg = i18n("Unable to restart CUPS server (pid = %1)").arg(serverPid);
00219 }
00220 return (msg.isEmpty());
00221 }
00222
00223 bool CupsdDialog::configure(const QString& filename, QWidget *parent, QString *msg)
00224 {
00225 bool needUpload(false);
00226 QString errormsg;
00227 bool result = true;
00228
00229
00230 if (!dynamically_loaded)
00231 cupsSetPasswordCB(getPassword);
00232
00233
00234 QString fn(filename);
00235 if (fn.isEmpty())
00236 {
00237 fn = cupsGetConf();
00238 if (fn.isEmpty())
00239 errormsg = i18n("Unable to retrieve configuration file from the CUPS server. "
00240 "You probably don't have the access permissions to perform this operation.");
00241 else needUpload = true;
00242 }
00243
00244
00245 if (!fn.isEmpty())
00246 {
00247 QFileInfo fi(fn);
00248 if (!fi.exists() || !fi.isReadable() || !fi.isWritable())
00249 errormsg = i18n("Internal error: file '%1' not readable/writable!").arg(fn);
00250
00251 if (fi.size() == 0)
00252 errormsg = i18n("Internal error: empty file '%1'!").arg(fn);
00253 }
00254
00255 if (!errormsg.isEmpty())
00256 {
00257 if ( !dynamically_loaded )
00258 KMessageBox::error(parent, errormsg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00259 result = false;
00260 }
00261 else
00262 {
00263 KGlobal::locale()->insertCatalogue("cupsdconf");
00264 CupsdDialog dlg(parent);
00265 if (dlg.setConfigFile(fn) && dlg.exec())
00266 {
00267 QCString encodedFn = QFile::encodeName(fn);
00268 if (!needUpload)
00269 KMessageBox::information(parent,
00270 i18n("The config file has not been uploaded to the "
00271 "CUPS server. The daemon will not be restarted."));
00272 else if (!cupsPutConf(encodedFn.data()))
00273 {
00274 errormsg = i18n("Unable to upload the configuration file to CUPS server. "
00275 "You probably don't have the access permissions to perform this operation.");
00276 if ( !dynamically_loaded )
00277 KMessageBox::error(parent, errormsg, i18n("CUPS configuration error"));
00278 result = false;
00279 }
00280 }
00281
00282 }
00283 if (needUpload)
00284 QFile::remove(fn);
00285
00286 if ( msg )
00287 *msg = errormsg;
00288 return result;
00289 }
00290
00291 void CupsdDialog::slotOk()
00292 {
00293 if (conf_ && !filename_.isEmpty())
00294 {
00295 bool ok(true);
00296 QString msg;
00297 CupsdConf newconf_;
00298 for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00299 ok = pagelist_.current()->saveConfig(&newconf_, msg);
00300
00301 newconf_.unknown_ = conf_->unknown_;
00302 if (!ok)
00303 {
00304 ;
00305 }
00306 else if (!newconf_.saveToFile(filename_))
00307 {
00308 msg = i18n("Unable to write configuration file %1").arg(filename_);
00309 ok = false;
00310 }
00311 if (!ok)
00312 {
00313 KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00314 }
00315 else
00316 KDialogBase::slotOk();
00317 }
00318 }
00319
00320 void CupsdDialog::slotUser1()
00321 {
00322 QWhatsThis::enterWhatsThisMode();
00323 }
00324
00325 int CupsdDialog::serverPid()
00326 {
00327 return getServerPid();
00328 }
00329
00330 int CupsdDialog::serverOwner()
00331 {
00332 int pid = getServerPid();
00333 if (pid > 0)
00334 {
00335 QString str;
00336 str.sprintf("/proc/%d/status",pid);
00337 QFile f(str);
00338 if (f.exists() && f.open(IO_ReadOnly))
00339 {
00340 QTextStream t(&f);
00341 while (!t.eof())
00342 {
00343 str = t.readLine();
00344 if (str.find("Uid:",0,false) == 0)
00345 {
00346 QStringList list = QStringList::split('\t', str, false);
00347 if (list.count() >= 2)
00348 {
00349 bool ok;
00350 int u = list[1].toInt(&ok);
00351 if (ok) return u;
00352 }
00353 }
00354 }
00355 }
00356 }
00357 return (-1);
00358 }
00359
00360 #include "cupsddialog.moc"