summaryrefslogtreecommitdiffstats
path: root/kdeprint/cups/cupsdconf2/cupsddialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdeprint/cups/cupsdconf2/cupsddialog.cpp')
-rw-r--r--kdeprint/cups/cupsdconf2/cupsddialog.cpp360
1 files changed, 360 insertions, 0 deletions
diff --git a/kdeprint/cups/cupsdconf2/cupsddialog.cpp b/kdeprint/cups/cupsdconf2/cupsddialog.cpp
new file mode 100644
index 000000000..a70b5b59e
--- /dev/null
+++ b/kdeprint/cups/cupsdconf2/cupsddialog.cpp
@@ -0,0 +1,360 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "cupsddialog.h"
+
+#include "cupsdpage.h"
+#include "cupsdconf.h"
+#include "cupsdsplash.h"
+#include "cupsdserverpage.h"
+#include "cupsdlogpage.h"
+#include "cupsdjobspage.h"
+#include "cupsdfilterpage.h"
+#include "cupsddirpage.h"
+#include "cupsdnetworkpage.h"
+#include "cupsdbrowsingpage.h"
+#include "cupsdsecuritypage.h"
+
+#include <qdir.h>
+#include <qvbox.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <qstringlist.h>
+#include <qwhatsthis.h>
+#include <kio/passdlg.h>
+#include <kguiitem.h>
+#include <kprocess.h>
+
+#include <signal.h>
+#include <cups/cups.h>
+
+static bool dynamically_loaded = false;
+static QString pass_string;
+
+extern "C"
+{
+#include "cups-util.h"
+ KDEPRINT_EXPORT bool restartServer(QString& msg)
+ {
+ return CupsdDialog::restartServer(msg);
+ }
+ KDEPRINT_EXPORT bool configureServer(QWidget *parent, QString& msg)
+ {
+ dynamically_loaded = true;
+ bool result = CupsdDialog::configure(QString::null, parent, &msg);
+ dynamically_loaded = false;
+ return result;
+ }
+}
+
+int getServerPid()
+{
+ QDir dir("/proc",QString::null,QDir::Name,QDir::Dirs);
+ for (uint i=0;i<dir.count();i++)
+ {
+ if (dir[i] == "." || dir[i] == ".." || dir[i] == "self") continue;
+ QFile f("/proc/" + dir[i] + "/cmdline");
+ if (f.exists() && f.open(IO_ReadOnly))
+ {
+ QTextStream t(&f);
+ QString line;
+ t >> line;
+ f.close();
+ if (line.right(5) == "cupsd" ||
+ line.right(6).left(5) == "cupsd") // second condition for 2.4.x kernels
+ // which add a null byte at the end
+ return dir[i].toInt();
+ }
+ }
+ return (-1);
+}
+
+const char* getPassword(const char*)
+{
+ QString user(cupsUser());
+ QString pass;
+
+ if (KIO::PasswordDialog::getNameAndPassword(user, pass, NULL) == QDialog::Accepted)
+ {
+ cupsSetUser(user.latin1());
+ pass_string = pass;
+ if (pass_string.isEmpty())
+ return "";
+ else
+ return pass_string.latin1();
+ }
+ else
+ return NULL;
+}
+
+//---------------------------------------------------
+
+CupsdDialog::CupsdDialog(QWidget *parent, const char *name)
+ : KDialogBase(IconList, "", Ok|Cancel|User1, Ok, parent, name, true, true, KGuiItem(i18n("Short Help"), "help"))
+{
+ KGlobal::iconLoader()->addAppDir("kdeprint");
+ KGlobal::locale()->insertCatalogue("cupsdconf");
+
+ setShowIconsInTreeList(true);
+ setRootIsDecorated(false);
+
+ pagelist_.setAutoDelete(false);
+ filename_ = "";
+ conf_ = 0;
+ constructDialog();
+
+ setCaption(i18n("CUPS Server Configuration"));
+
+ //resize(500, 400);
+}
+
+CupsdDialog::~CupsdDialog()
+{
+ delete conf_;
+}
+
+void CupsdDialog::addConfPage(CupsdPage *page)
+{
+ QPixmap icon = KGlobal::instance()->iconLoader()->loadIcon(
+ page->pixmap(),
+ KIcon::NoGroup,
+ KIcon::SizeMedium
+ );
+
+ QVBox *box = addVBoxPage(page->pageLabel(), page->header(), icon);
+ page->reparent(box, QPoint(0,0));
+ pagelist_.append(page);
+}
+
+void CupsdDialog::constructDialog()
+{
+ addConfPage(new CupsdSplash(0));
+ addConfPage(new CupsdServerPage(0));
+ addConfPage(new CupsdNetworkPage(0));
+ addConfPage(new CupsdSecurityPage(0));
+ addConfPage(new CupsdLogPage(0));
+ addConfPage(new CupsdJobsPage(0));
+ addConfPage(new CupsdFilterPage(0));
+ addConfPage(new CupsdDirPage(0));
+ addConfPage(new CupsdBrowsingPage(0));
+
+ conf_ = new CupsdConf();
+ for (pagelist_.first();pagelist_.current();pagelist_.next())
+ {
+ pagelist_.current()->setInfos(conf_);
+ }
+}
+
+bool CupsdDialog::setConfigFile(const QString& filename)
+{
+ filename_ = filename;
+ if (!conf_->loadFromFile(filename_))
+ {
+ KMessageBox::error(this, i18n("Error while loading configuration file!"), i18n("CUPS Configuration Error"));
+ return false;
+ }
+ if (conf_->unknown_.count() > 0)
+ {
+ // there were some unknown options, warn the user
+ QString msg;
+ for (QValueList< QPair<QString,QString> >::ConstIterator it=conf_->unknown_.begin(); it!=conf_->unknown_.end(); ++it)
+ msg += ((*it).first + " = " + (*it).second + "<br>");
+ msg.prepend("<p>" + i18n("Some options were not recognized by this configuration tool. "
+ "They will be left untouched and you won't be able to change them.") + "</p>");
+ KMessageBox::sorry(this, msg, i18n("Unrecognized Options"));
+ }
+ bool ok(true);
+ QString msg;
+ for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
+ ok = pagelist_.current()->loadConfig(conf_, msg);
+ if (!ok)
+ {
+ KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
+ return false;
+ }
+ return true;
+}
+
+bool CupsdDialog::restartServer(QString& msg)
+{
+ int serverPid = getServerPid();
+ msg.truncate(0);
+ if (serverPid <= 0)
+ {
+ msg = i18n("Unable to find a running CUPS server");
+ }
+ else
+ {
+ bool success = false;
+ if (getuid() == 0 )
+ success = (::kill(serverPid, SIGHUP) == 0);
+ else
+ {
+ KProcess proc;
+ proc << "kdesu" << "-c" << "kill -SIGHUP " + QString::number( serverPid );
+ success = proc.start( KProcess::Block ) && proc.normalExit();
+ }
+ if( !success )
+ msg = i18n("Unable to restart CUPS server (pid = %1)").arg(serverPid);
+ }
+ return (msg.isEmpty());
+}
+
+bool CupsdDialog::configure(const QString& filename, QWidget *parent, QString *msg)
+{
+ bool needUpload(false);
+ QString errormsg;
+ bool result = true;
+
+ // init password dialog if needed
+ if (!dynamically_loaded)
+ cupsSetPasswordCB(getPassword);
+
+ // load config file from server
+ QString fn(filename);
+ if (fn.isEmpty())
+ {
+ fn = cupsGetConf();
+ if (fn.isEmpty())
+ errormsg = i18n("Unable to retrieve configuration file from the CUPS server. "
+ "You probably don't have the access permissions to perform this operation.");
+ else needUpload = true;
+ }
+
+ // check read state (only if needed)
+ if (!fn.isEmpty())
+ {
+ QFileInfo fi(fn);
+ if (!fi.exists() || !fi.isReadable() || !fi.isWritable())
+ errormsg = i18n("Internal error: file '%1' not readable/writable!").arg(fn);
+ // check file size
+ if (fi.size() == 0)
+ errormsg = i18n("Internal error: empty file '%1'!").arg(fn);
+ }
+
+ if (!errormsg.isEmpty())
+ {
+ if ( !dynamically_loaded )
+ KMessageBox::error(parent, errormsg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
+ result = false;
+ }
+ else
+ {
+ KGlobal::locale()->insertCatalogue("cupsdconf"); // Must be before dialog is created to translate "Short Help"
+ CupsdDialog dlg(parent);
+ if (dlg.setConfigFile(fn) && dlg.exec())
+ {
+ QCString encodedFn = QFile::encodeName(fn);
+ if (!needUpload)
+ KMessageBox::information(parent,
+ i18n("The config file has not been uploaded to the "
+ "CUPS server. The daemon will not be restarted."));
+ else if (!cupsPutConf(encodedFn.data()))
+ {
+ errormsg = i18n("Unable to upload the configuration file to CUPS server. "
+ "You probably don't have the access permissions to perform this operation.");
+ if ( !dynamically_loaded )
+ KMessageBox::error(parent, errormsg, i18n("CUPS configuration error"));
+ result = false;
+ }
+ }
+
+ }
+ if (needUpload)
+ QFile::remove(fn);
+
+ if ( msg )
+ *msg = errormsg;
+ return result;
+}
+
+void CupsdDialog::slotOk()
+{
+ if (conf_ && !filename_.isEmpty())
+ { // try to save the file
+ bool ok(true);
+ QString msg;
+ CupsdConf newconf_;
+ for (pagelist_.first();pagelist_.current() && ok;pagelist_.next())
+ ok = pagelist_.current()->saveConfig(&newconf_, msg);
+ // copy unknown options
+ newconf_.unknown_ = conf_->unknown_;
+ if (!ok)
+ {
+ ; // do nothing
+ }
+ else if (!newconf_.saveToFile(filename_))
+ {
+ msg = i18n("Unable to write configuration file %1").arg(filename_);
+ ok = false;
+ }
+ if (!ok)
+ {
+ KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"), i18n("CUPS Configuration Error"));
+ }
+ else
+ KDialogBase::slotOk();
+ }
+}
+
+void CupsdDialog::slotUser1()
+{
+ QWhatsThis::enterWhatsThisMode();
+}
+
+int CupsdDialog::serverPid()
+{
+ return getServerPid();
+}
+
+int CupsdDialog::serverOwner()
+{
+ int pid = getServerPid();
+ if (pid > 0)
+ {
+ QString str;
+ str.sprintf("/proc/%d/status",pid);
+ QFile f(str);
+ if (f.exists() && f.open(IO_ReadOnly))
+ {
+ QTextStream t(&f);
+ while (!t.eof())
+ {
+ str = t.readLine();
+ if (str.find("Uid:",0,false) == 0)
+ {
+ QStringList list = QStringList::split('\t', str, false);
+ if (list.count() >= 2)
+ {
+ bool ok;
+ int u = list[1].toInt(&ok);
+ if (ok) return u;
+ }
+ }
+ }
+ }
+ }
+ return (-1);
+}
+
+#include "cupsddialog.moc"