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 <tqdir.h>
00035 #include <tqvbox.h>
00036 #include <tdemessagebox.h>
00037 #include <tdelocale.h>
00038 #include <tqfile.h>
00039 #include <tqfileinfo.h>
00040 #include <tdeglobal.h>
00041 #include <kiconloader.h>
00042 #include <tqstringlist.h>
00043 #include <tqwhatsthis.h>
00044 #include <tdeio/passdlg.h>
00045 #include <kguiitem.h>
00046 #include <kprocess.h>
00047 #include <tqprocess.h>
00048
00049 #include <stdlib.h>
00050 #include <signal.h>
00051 #include <cups/cups.h>
00052
00053 static bool dynamically_loaded = false;
00054 static TQString pass_string;
00055
00056 extern "C"
00057 {
00058 #include "cups-util.h"
00059 TDEPRINT_EXPORT bool restartServer(TQString& msg)
00060 {
00061 return CupsdDialog::restartServer(msg);
00062 }
00063 TDEPRINT_EXPORT bool configureServer(TQWidget *parent, TQString& msg)
00064 {
00065 dynamically_loaded = true;
00066 bool result = CupsdDialog::configure(TQString::null, parent, &msg);
00067 dynamically_loaded = false;
00068 return result;
00069 }
00070 }
00071
00072 int getServerPid()
00073 {
00074 #if defined(__OpenBSD__) || defined(__FreeBSD__)
00075 TQProcess *proc = new TQProcess();
00076 proc->addArgument("pgrep");
00077 proc->addArgument("cupsd");
00078 proc->start();
00079 while (proc->isRunning());
00080 TQString pidString = proc->readLineStdout();
00081 bool ok;
00082 int pid = pidString.toInt(&ok);
00083 if (ok) return pid;
00084 return (-1);
00085 #else
00086 TQDir dir("/proc",TQString::null,TQDir::Name,TQDir::Dirs);
00087 for (uint i=0;i<dir.count();i++)
00088 {
00089 if (dir[i] == "." || dir[i] == ".." || dir[i] == "self") continue;
00090 TQFile f("/proc/" + dir[i] + "/cmdline");
00091 if (f.exists() && f.open(IO_ReadOnly))
00092 {
00093 TQTextStream t(&f);
00094 TQString line;
00095 t >> line;
00096 f.close();
00097 if (line.right(5) == "cupsd" ||
00098 line.right(6).left(5) == "cupsd")
00099
00100 return dir[i].toInt();
00101 }
00102 }
00103 return (-1);
00104 #endif
00105 }
00106
00107 const char* getPassword(const char*)
00108 {
00109 TQString user(cupsUser());
00110 TQString pass;
00111
00112 if (TDEIO::PasswordDialog::getNameAndPassword(user, pass, NULL) == TQDialog::Accepted)
00113 {
00114 cupsSetUser(user.latin1());
00115 pass_string = pass;
00116 if (pass_string.isEmpty())
00117 return "";
00118 else
00119 return pass_string.latin1();
00120 }
00121 else
00122 return NULL;
00123 }
00124
00125
00126
00127 CupsdDialog::CupsdDialog(TQWidget *parent, const char *name)
00128 : KDialogBase(IconList, "", Ok|Cancel|User1, Ok, parent, name, true, true, KGuiItem(i18n("Short Help"), "help"))
00129 {
00130 TDEGlobal::iconLoader()->addAppDir("tdeprint");
00131 TDEGlobal::locale()->insertCatalogue("cupsdconf");
00132
00133 setShowIconsInTreeList(true);
00134 setRootIsDecorated(false);
00135
00136 pagelist_.setAutoDelete(false);
00137 filename_ = "";
00138 conf_ = 0;
00139 constructDialog();
00140
00141 setCaption(i18n("CUPS Server Configuration"));
00142
00143
00144 }
00145
00146 CupsdDialog::~CupsdDialog()
00147 {
00148 delete conf_;
00149 }
00150
00151 void CupsdDialog::addConfPage(CupsdPage *page)
00152 {
00153 TQPixmap icon = TDEGlobal::instance()->iconLoader()->loadIcon(
00154 page->pixmap(),
00155 TDEIcon::NoGroup,
00156 TDEIcon::SizeMedium
00157 );
00158
00159 TQVBox *box = addVBoxPage(page->pageLabel(), page->header(), icon);
00160 page->reparent(box, TQPoint(0,0));
00161 pagelist_.append(page);
00162 }
00163
00164 void CupsdDialog::constructDialog()
00165 {
00166 addConfPage(new CupsdSplash(0));
00167 addConfPage(new CupsdServerPage(0));
00168 addConfPage(new CupsdNetworkPage(0));
00169 addConfPage(new CupsdSecurityPage(0));
00170 addConfPage(new CupsdLogPage(0));
00171 addConfPage(new CupsdJobsPage(0));
00172 addConfPage(new CupsdFilterPage(0));
00173 addConfPage(new CupsdDirPage(0));
00174 addConfPage(new CupsdBrowsingPage(0));
00175
00176 conf_ = new CupsdConf();
00177 for (pagelist_.first();pagelist_.current();pagelist_.next())
00178 {
00179 pagelist_.current()->setInfos(conf_);
00180 }
00181 }
00182
00183 bool CupsdDialog::setConfigFile(const TQString& filename)
00184 {
00185 filename_ = filename;
00186 if (!conf_->loadFromFile(filename_))
00187 {
00188 KMessageBox::error(this, i18n("Error while loading configuration file!"), i18n("CUPS Configuration Error"));
00189 return false;
00190 }
00191 if (conf_->unknown_.count() > 0)
00192 {
00193
00194 TQString msg;
00195 for (TQValueList< TQPair<TQString,TQString> >::ConstIterator it=conf_->unknown_.begin(); it!=conf_->unknown_.end(); ++it)
00196 msg += ((*it).first + " = " + (*it).second + "<br>");
00197 msg.prepend("<p>" + i18n("Some options were not recognized by this configuration tool. "
00198 "They will be left untouched and you won't be able to change them.") + "</p>");
00199 KMessageBox::sorry(this, msg, i18n("Unrecognized Options"));
00200 }
00201 bool ok(true);
00202 TQString msg;
00203 for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00204 ok = pagelist_.current()->loadConfig(conf_, msg);
00205 if (!ok)
00206 {
00207 KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00208 return false;
00209 }
00210 return true;
00211 }
00212
00213 bool CupsdDialog::restartServer(TQString& msg)
00214 {
00215 int serverPid = getServerPid();
00216 msg.truncate(0);
00217 if (serverPid <= 0)
00218 {
00219 msg = i18n("Unable to find a running CUPS server");
00220 }
00221 else
00222 {
00223 bool success = false;
00224 TDEProcess proc;
00225 proc << "tdesu" << "-c" << "/etc/init.d/cupsys restart";
00226 success = proc.start( TDEProcess::Block ) && proc.normalExit();
00227 if( !success )
00228 msg = i18n("Unable to restart CUPS server (pid = %1)").arg(serverPid);
00229 }
00230 return (msg.isEmpty());
00231 }
00232
00233 bool CupsdDialog::configure(const TQString& filename, TQWidget *parent, TQString *msg)
00234 {
00235 bool needUpload(false);
00236 TQString errormsg;
00237 bool result = true;
00238
00239
00240 if (!dynamically_loaded)
00241 cupsSetPasswordCB(getPassword);
00242
00243
00244 TQString fn(filename);
00245 if (fn.isEmpty())
00246 {
00247 fn = cupsGetConf();
00248 if (fn.isEmpty())
00249 errormsg = i18n("Unable to retrieve configuration file from the CUPS server. "
00250 "You probably don't have the access permissions to perform this operation.");
00251 else needUpload = true;
00252 }
00253
00254
00255 if (!fn.isEmpty())
00256 {
00257 TQFileInfo fi(fn);
00258 if (!fi.exists() || !fi.isReadable() || !fi.isWritable())
00259 errormsg = i18n("Internal error: file '%1' not readable/writable!").arg(fn);
00260
00261 if (fi.size() == 0)
00262 errormsg = i18n("Internal error: empty file '%1'!").arg(fn);
00263 }
00264
00265 if (!errormsg.isEmpty())
00266 {
00267 if ( !dynamically_loaded )
00268 KMessageBox::error(parent, errormsg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00269 result = false;
00270 }
00271 else
00272 {
00273 TDEGlobal::locale()->insertCatalogue("cupsdconf");
00274 CupsdDialog dlg(parent);
00275 if (dlg.setConfigFile(fn) && dlg.exec())
00276 {
00277 TQCString encodedFn = TQFile::encodeName(fn);
00278 if (!needUpload)
00279 KMessageBox::information(parent,
00280 i18n("The config file has not been uploaded to the "
00281 "CUPS server. The daemon will not be restarted."));
00282 else if (!cupsPutConf(encodedFn.data()))
00283 {
00284 errormsg = i18n("Unable to upload the configuration file to CUPS server. "
00285 "You probably don't have the access permissions to perform this operation.");
00286 if ( !dynamically_loaded )
00287 KMessageBox::error(parent, errormsg, i18n("CUPS configuration error"));
00288 result = false;
00289 }
00290 }
00291
00292 }
00293 if (needUpload)
00294 TQFile::remove(fn);
00295
00296 if ( msg )
00297 *msg = errormsg;
00298 return result;
00299 }
00300
00301 void CupsdDialog::slotOk()
00302 {
00303 if (conf_ && !filename_.isEmpty())
00304 {
00305 bool ok(true);
00306 TQString msg;
00307 CupsdConf newconf_;
00308 for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
00309 ok = pagelist_.current()->saveConfig(&newconf_, msg);
00310
00311 newconf_.unknown_ = conf_->unknown_;
00312 if (!ok)
00313 {
00314 ;
00315 }
00316 else if (!newconf_.saveToFile(filename_))
00317 {
00318 msg = i18n("Unable to write configuration file %1").arg(filename_);
00319 ok = false;
00320 }
00321 if (!ok)
00322 {
00323 KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
00324 }
00325 else
00326 KDialogBase::slotOk();
00327 }
00328 }
00329
00330 void CupsdDialog::slotUser1()
00331 {
00332 TQWhatsThis::enterWhatsThisMode();
00333 }
00334
00335 int CupsdDialog::serverPid()
00336 {
00337 return getServerPid();
00338 }
00339
00340 int CupsdDialog::serverOwner()
00341 {
00342 int pid = getServerPid();
00343 if (pid > 0)
00344 {
00345 TQString str;
00346 str.sprintf("/proc/%d/status",pid);
00347 TQFile f(str);
00348 if (f.exists() && f.open(IO_ReadOnly))
00349 {
00350 TQTextStream t(&f);
00351 while (!t.eof())
00352 {
00353 str = t.readLine();
00354 if (str.find("Uid:",0,false) == 0)
00355 {
00356 TQStringList list = TQStringList::split('\t', str, false);
00357 if (list.count() >= 2)
00358 {
00359 bool ok;
00360 int u = list[1].toInt(&ok);
00361 if (ok) return u;
00362 }
00363 }
00364 }
00365 }
00366 }
00367 return (-1);
00368 }
00369
00370 #include "cupsddialog.moc"