• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDEPrint

cupsdconf.cpp

Go to the documentation of this file.
00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License version 2 as published by the Free Software Foundation.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Library General Public License
00015  *  along with this library; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
00018  **/
00019 
00020 #include "cupsdconf.h"
00021 
00022 #include <config.h>
00023 
00024 #include <QtCore/QFile>
00025 #include <QtCore/QRegExp>
00026 #include <klocale.h>
00027 #include <kdebug.h>
00028 #include <kconfiggroup.h>
00029 
00030 #include <stdlib.h>
00031 #include <cups/cups.h>
00032 #include <cups/ipp.h>
00033 #include <cups/language.h>
00034 
00035 QString findDir(const QStringList& list)
00036 {
00037     for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
00038         if (QFile::exists(*it))
00039             return *it;
00040     // if nothing found, just use the first as default value
00041     return list[0];
00042 }
00043 
00044 void splitSizeSpec(const QString& s, int& sz, int& suff)
00045 {
00046     int p = s.indexOf(QRegExp("\\D"));
00047     sz = s.mid(0, p).toInt();
00048     if (p != -1) {
00049         switch (s[p].toLatin1()) {
00050         case 'k': suff = UNIT_KB; break;
00051         default:
00052         case 'm': suff = UNIT_MB; break;
00053         case 'g': suff = UNIT_GB; break;
00054         case 't': suff = UNIT_TILE; break;
00055         }
00056     } else
00057         suff = UNIT_MB;
00058 }
00059 
00060 CupsdConf::CupsdConf()
00061 {
00062     // start by trying to find CUPS directories (useful later)
00063     datadir_ = findDir(QStringList("/usr/share/cups")
00064                        << "/usr/local/share/cups"
00065                        << "/opt/share/cups"
00066                        << "/opt/local/share/cups");
00067     documentdir_ = findDir(QStringList(datadir_ + "/doc")
00068                            << datadir_.left(datadir_.length() - 5) + "/doc/cups");
00069     //fontpath_ << (datadir_+"/fonts");
00070     requestdir_ = findDir(QStringList("/var/spool/cups")
00071                           << "/var/cups");
00072     serverbin_ = findDir(QStringList("/usr/lib" KDELIBSUFF "/cups")
00073                          << "/usr/local/lib" KDELIBSUFF "/cups"
00074                          << "/opt/lib" KDELIBSUFF "/cups"
00075                          << "/opt/local/lib" KDELIBSUFF "/cups");
00076     serverfiles_ = findDir(QStringList("/etc/cups")
00077                            << "/usr/local/etc/cups");
00078     tmpfiles_ = requestdir_ + "/tmp";
00079 
00080     // other options
00081     servername_.clear();
00082     serveradmin_.clear();
00083     classification_ = CLASS_NONE;
00084     otherclassname_.clear();
00085     classoverride_ = false;
00086     charset_ = "utf-8";
00087     language_ = "en";
00088     printcap_ = "/etc/printcap";
00089     printcapformat_ = PRINTCAP_BSD;
00090     remoteroot_ = "remroot";
00091     systemgroup_ = "sys";
00092     encryptcert_ = serverfiles_ + "/ssl/server.crt";
00093     encryptkey_ = serverfiles_ + "/ssl/server.key";
00094     hostnamelookup_ = HOSTNAME_OFF;
00095     keepalive_ = true;
00096     keepalivetimeout_ = 60;
00097     maxclients_ = 100;
00098     maxrequestsize_ = "0";
00099     clienttimeout_ = 300;
00100     // listenaddresses_
00101     QString logdir = findDir(QStringList("/var/log/cups")
00102                              << "/var/spool/cups/log"
00103                              << "/var/cups/log");
00104     accesslog_ = logdir + "/access_log";
00105     errorlog_ = logdir + "/error_log";
00106     pagelog_ = logdir + "/page_log";
00107     maxlogsize_ = "1m";
00108     loglevel_ = LOGLEVEL_INFO;
00109     keepjobhistory_ = true;
00110     keepjobfiles_ = false;
00111     autopurgejobs_ = false;
00112     maxjobs_ = 0;
00113     maxjobsperprinter_ = 0;
00114     maxjobsperuser_ = 0;
00115     user_ = "lp";
00116     group_ = "sys";
00117     ripcache_ = "8m";
00118     filterlimit_ = 0;
00119     browsing_ = true;
00120     browseprotocols_ << "CUPS";
00121     browseport_ = ippPort();
00122     browseinterval_ = 30;
00123     browsetimeout_ = 300;
00124     // browseaddresses_
00125     browseorder_ = ORDER_ALLOW_DENY;
00126     useimplicitclasses_ = true;
00127     hideimplicitmembers_ = true;
00128     useshortnames_ = true;
00129     useanyclasses_ = false;
00130 
00131     loadAvailableResources();
00132 }
00133 
00134 CupsdConf::~CupsdConf()
00135 {
00136 }
00137 
00138 bool CupsdConf::loadFromFile(const QString& filename)
00139 {
00140     QFile f(filename);
00141     if (!f.exists() || !f.open(QIODevice::ReadOnly)) return false;
00142     else {
00143         QTextStream t(&f);
00144         QString line;
00145         bool done(false), value(true);
00146         while (!done && value) {
00147             line = t.readLine().simplified();
00148             if (line.isEmpty()) {
00149                 if (t.atEnd()) done = true;
00150                 else continue;
00151             } else if (line[0] == '#') continue;
00152             else if (line.startsWith("<location", Qt::CaseInsensitive)) {
00153                 CupsLocation *location = new CupsLocation();
00154                 locations_.append(location);
00155                 if (!location->parseResource(line) || !parseLocation(location, t))
00156                     value = false;
00157                 // search corresponding resource
00158                 QListIterator<CupsResource*> it(resources_);
00159                 while (it.hasNext()) {
00160                     CupsResource *resource(it.next());
00161                     if (resource->path_ == location->resourcename_)
00162                         location->resource_ = resource;
00163                 }
00164             } else value = parseOption(line);
00165         }
00166         f.close();
00167         return value;
00168     }
00169 }
00170 
00171 bool CupsdConf::saveToFile(const QString& filename)
00172 {
00173     QFile f(filename);
00174     if (!f.open(QIODevice::WriteOnly))
00175         return false;
00176     else {
00177         QTextStream t(&f);
00178         t << comments_["header"] << endl;
00179         t << "# Server" << endl << endl;
00180 
00181         t << comments_["servername"] << endl;
00182         if (!servername_.isEmpty())
00183             t << "ServerName " << servername_ << endl;
00184 
00185         t << endl << comments_["serveradmin"] << endl;
00186         if (!serveradmin_.isEmpty())
00187             t << "ServerAdmin " << serveradmin_ << endl;
00188 
00189         t << endl << comments_["classification"] << endl;
00190         t << "Classification ";
00191         switch (classification_) {
00192         default:
00193         case CLASS_NONE: t << "none"; break;
00194         case CLASS_CLASSIFIED: t << "classified"; break;
00195         case CLASS_CONFIDENTIAL: t << "confidential"; break;
00196         case CLASS_SECRET: t << "secret"; break;
00197         case CLASS_TOPSECRET: t << "topsecret"; break;
00198         case CLASS_UNCLASSIFIED: t << "unclassified"; break;
00199         case CLASS_OTHER: t << otherclassname_; break;
00200         }
00201         t << endl;
00202 
00203         t << endl << comments_["classifyoverride"] << endl;
00204         if (classification_ != CLASS_NONE) t << "ClassifyOverride " << (classoverride_ ? "Yes" : "No") << endl;
00205 
00206         t << endl << comments_["defaultcharset"] << endl;
00207         t << "DefaultCharset " << charset_.toUpper() << endl;
00208 
00209         t << endl << comments_["defaultlanguage"] << endl;
00210         t << "DefaultLanguage " << language_.toLower() << endl;
00211 
00212         t << endl << comments_["printcap"] << endl;
00213         t << "Printcap " << printcap_ << endl;
00214 
00215         t << endl << comments_["printcapformat"] << endl;
00216         t << "PrintcapFormat " << (printcapformat_ == PRINTCAP_SOLARIS ? "Solaris" : "BSD") << endl;
00217 
00218         t << endl << "# Security" << endl;
00219         t << endl << comments_["remoteroot"] << endl;
00220         t << "RemoteRoot " << remoteroot_ << endl;
00221 
00222         t << endl << comments_["systemgroup"] << endl;
00223         t << "SystemGroup " << systemgroup_ << endl;
00224 
00225         t << endl << comments_["servercertificate"] << endl;
00226         t << "ServerCertificate " << encryptcert_ << endl;
00227 
00228         t << endl << comments_["serverkey"] << endl;
00229         t << "ServerKey " << encryptkey_ << endl;
00230 
00231         t << endl << comments_["locations"] << endl;
00232         QListIterator<CupsLocation*> it(locations_);
00233         while (it.hasNext()) {
00234             CupsLocation *loc = (it.next());
00235             t << "<Location " << loc->resourcename_ << ">" << endl;
00236             if (loc->authtype_ != AUTHTYPE_NONE) {
00237                 t << "AuthType ";
00238                 switch (loc->authtype_) {
00239                 case AUTHTYPE_BASIC: t << "Basic"; break;
00240                 case AUTHTYPE_DIGEST: t << "Digest"; break;
00241                 }
00242                 t << endl;
00243             }
00244             if (loc->authclass_ != AUTHCLASS_ANONYMOUS) {
00245                 switch (loc->authclass_) {
00246                 case AUTHCLASS_USER:
00247                     if (!loc->authname_.isEmpty())
00248                         t << "Require user " << loc->authname_ << endl;
00249                     else
00250                         t << "AuthClass User" << endl;
00251                     break;
00252                 case AUTHCLASS_GROUP:
00253                     if (!loc->authname_.isEmpty())
00254                         t << "Require group " << loc->authname_ << endl;
00255                     else
00256                         t << "AuthClass Group" << endl;
00257                     break;
00258                 case AUTHCLASS_SYSTEM:
00259                     t << "AuthClass System" << endl;
00260                     break;
00261                 }
00262             }
00263             t << "Encryption ";
00264             switch (loc->encryption_) {
00265             case ENCRYPT_ALWAYS: t << "Always"; break;
00266             case ENCRYPT_NEVER: t << "Never"; break;
00267             case ENCRYPT_REQUIRED: t << "Required"; break;
00268             default:
00269             case ENCRYPT_IFREQUESTED: t << "IfRequested"; break;
00270             }
00271             t << endl;
00272             t << "Satisfy " << (loc->satisfy_ == SATISFY_ALL ? "All" : "Any") << endl;
00273             t << "Order " << (loc->order_ == ORDER_ALLOW_DENY ? "allow,deny" : "deny,allow") << endl;
00274             for (QStringList::ConstIterator it = loc->addresses_.begin(); it != loc->addresses_.end(); ++it)
00275                 t << *it << endl;
00276             t << "</Location>" << endl;
00277         }
00278 
00279         t << endl << "# Network" << endl;
00280         t << endl << comments_["hostnamelookups"] << endl;
00281         t << "HostnameLookups ";
00282         switch (hostnamelookup_) {
00283         default:
00284         case HOSTNAME_OFF: t << "Off"; break;
00285         case HOSTNAME_ON: t << "On"; break;
00286         case HOSTNAME_DOUBLE: t << "Double"; break;
00287         }
00288         t << endl;
00289 
00290         t << endl << comments_["keepalive"] << endl;
00291         t << "KeepAlive " << (keepalive_ ? "On" : "Off") << endl;
00292 
00293         t << endl << comments_["keepalivetimeout"] << endl;
00294         t << "KeepAliveTimeout " << keepalivetimeout_ << endl;
00295 
00296         t << endl << comments_["maxclients"] << endl;
00297         t << "MaxClients " << maxclients_ << endl;
00298 
00299         t << endl << comments_["maxrequestsize"] << endl;
00300         t << "MaxRequestSize " << maxrequestsize_ << endl;
00301 
00302         t << endl << comments_["timeout"] << endl;
00303         t << "Timeout " << clienttimeout_ << endl;
00304 
00305         t << endl << comments_["listen"] << endl;
00306         for (QStringList::ConstIterator it = listenaddresses_.begin(); it != listenaddresses_.end(); ++it)
00307             t << *it << endl;
00308 
00309         t << endl << "# Log" << endl;
00310         t << endl << comments_["accesslog"] << endl;
00311         t << "AccessLog " << accesslog_ << endl;
00312 
00313         t << endl << comments_["errorlog"] << endl;
00314         t << "ErrorLog " << errorlog_ << endl;
00315 
00316         t << endl << comments_["pagelog"] << endl;
00317         t << "PageLog " << pagelog_ << endl;
00318 
00319         t << endl << comments_["maxlogsize"] << endl;
00320         //t << "MaxLogSize " << maxlogsize_ << "m" << endl;
00321         t << "MaxLogSize " << maxlogsize_ << endl;
00322 
00323         t << endl << comments_["loglevel"] << endl;
00324         t << "LogLevel ";
00325         switch (loglevel_) {
00326         case LOGLEVEL_NONE: t << "none"; break;
00327         default:
00328         case LOGLEVEL_INFO: t << "info"; break;
00329         case LOGLEVEL_ERROR: t << "error"; break;
00330         case LOGLEVEL_WARN: t << "warn"; break;
00331         case LOGLEVEL_DEBUG: t << "debug"; break;
00332         case LOGLEVEL_DEBUG2: t << "debug2"; break;
00333         }
00334         t << endl;
00335 
00336         t << endl << "# Jobs" << endl;
00337         t << endl << comments_["preservejobhistory"] << endl;
00338         t << "PreserveJobHistory " << (keepjobhistory_ ? "On" : "Off") << endl;
00339 
00340         t << endl << comments_["preservejobfiles"] << endl;
00341         if (keepjobhistory_) t << "PreserveJobFiles " << (keepjobfiles_ ? "On" : "Off") << endl;
00342 
00343         t << endl << comments_["autopurgejobs"] << endl;
00344         if (keepjobhistory_) t << "AutoPurgeJobs " << (autopurgejobs_ ? "Yes" : "No") << endl;
00345 
00346         t << endl << comments_["maxjobs"] << endl;
00347         t << "MaxJobs " << maxjobs_ << endl;
00348 
00349         t << endl << comments_["maxjobsperprinter"] << endl;
00350         t << "MaxJobsPerPrinter " << maxjobsperprinter_ << endl;
00351 
00352         t << endl << comments_["maxjobsperuser"] << endl;
00353         t << "MaxJobsPerUser " << maxjobsperuser_ << endl;
00354 
00355         t << endl << "# Filter" << endl;
00356         t << endl << comments_["user"] << endl;
00357         t << "User " << user_ << endl;
00358 
00359         t << endl << comments_["group"] << endl;
00360         t << "Group " << group_ << endl;
00361 
00362         t << endl << comments_["ripcache"] << endl;
00363         t << "RIPCache " << ripcache_ << endl;
00364 
00365         t << endl << comments_["filterlimit"] << endl;
00366         t << "FilterLimit " << filterlimit_ << endl;
00367 
00368         t << endl << "# Directories" << endl;
00369         t << endl << comments_["datadir"] << endl;
00370         t << "DataDir " << datadir_ << endl;
00371 
00372         t << endl << comments_["documentroot"] << endl;
00373         t << "DocumentRoot " << documentdir_ << endl;
00374 
00375         t << endl << comments_["fontpath"] << endl;
00376         for (QStringList::ConstIterator it = fontpath_.begin(); it != fontpath_.end(); ++it)
00377             t << "FontPath " << *it << endl;
00378 
00379         t << endl << comments_["requestroot"] << endl;
00380         t << "RequestRoot " << requestdir_ << endl;
00381 
00382         t << endl << comments_["serverbin"] << endl;
00383         t << "ServerBin " << serverbin_ << endl;
00384 
00385         t << endl << comments_["serverroot"] << endl;
00386         t << "ServerRoot " << serverfiles_ << endl;
00387 
00388         t << endl << comments_["tempdir"] << endl;
00389         t << "TempDir " << tmpfiles_ << endl;
00390 
00391         t << endl << "# Browsing" << endl;
00392         t << endl << comments_["browsing"] << endl;
00393         t << "Browsing " << (browsing_ ? "On" : "Off") << endl;
00394 
00395         t << endl << comments_["browseprotocols"] << endl;
00396         if (browsing_) {
00397             t << "BrowseProtocols ";
00398             for (QStringList::ConstIterator it = browseprotocols_.begin(); it != browseprotocols_.end(); ++it)
00399                 t << (*it).toUpper() << " ";
00400             t << endl;
00401         }
00402 
00403         t << endl << comments_["browseport"] << endl;
00404         if (browsing_) t << "BrowsePort " << browseport_ << endl;
00405 
00406         t << endl << comments_["browseinterval"] << endl;
00407         if (browsing_) t << "BrowseInterval " << browseinterval_ << endl;
00408 
00409         t << endl << comments_["browsetimeout"] << endl;
00410         if (browsing_) t << "BrowseTimeout " << browsetimeout_ << endl;
00411 
00412         t << endl << comments_["browseaddress"] << endl;
00413         if (browsing_)
00414             for (QStringList::ConstIterator it = browseaddresses_.begin(); it != browseaddresses_.end(); ++it)
00415                 if ((*it).startsWith("Send"))
00416                     t << "BrowseAddress " << (*it).mid(5) << endl;
00417                 else
00418                     t << "Browse" << (*it) << endl;
00419 
00420         t << endl << comments_["browseorder"] << endl;
00421         if (browsing_) t << "BrowseOrder " << (browseorder_ == ORDER_ALLOW_DENY ? "allow,deny" : "deny,allow") << endl;
00422 
00423         t << endl << comments_["implicitclasses"] << endl;
00424         if (browsing_) t << "ImplicitClasses " << (useimplicitclasses_ ? "On" : "Off") << endl;
00425 
00426         t << endl << comments_["implicitanyclasses"] << endl;
00427         if (browsing_) t << "ImplicitAnyClasses " << (useanyclasses_ ? "On" : "Off") << endl;
00428 
00429         t << endl << comments_["hideimplicitmembers"] << endl;
00430         if (browsing_) t << "HideImplicitMembers " << (hideimplicitmembers_ ? "Yes" : "No") << endl;
00431 
00432         t << endl << comments_["browseshortnames"] << endl;
00433         if (browsing_) t << "BrowseShortNames " << (useshortnames_ ? "Yes" : "No") << endl;
00434 
00435         t << endl << "# Unknown" << endl;
00436         for (QList< QPair<QString, QString> >::ConstIterator it = unknown_.begin(); it != unknown_.end(); ++it)
00437             t << (*it).first << " " << (*it).second << endl;
00438 
00439         return true;
00440     }
00441 }
00442 
00443 bool CupsdConf::parseLocation(CupsLocation *location, QTextStream& file)
00444 {
00445     QString line;
00446     bool done(false);
00447     bool value(true);
00448     while (!done && value) {
00449         line = file.readLine().simplified();
00450         if (line.isEmpty()) {
00451             if (file.atEnd()) {
00452                 value = false;
00453                 done = true;
00454             } else continue;
00455         } else if (line[0] == '#') continue;
00456         else if (line.toLower() == "</location>") done = true;
00457         else value = location->parseOption(line);
00458     }
00459     return value;
00460 }
00461 
00462 bool CupsdConf::parseOption(const QString& line)
00463 {
00464     int p(-1);
00465     QString keyword, value, l(line.simplified());
00466 
00467     if ((p = l.indexOf(' ')) != -1) {
00468         keyword = l.left(p).toLower();
00469         value = l.mid(p + 1);
00470     } else {
00471         keyword = l.toLower();
00472     }
00473 
00474     //kDebug() << "cupsd.conf keyword=" << keyword;
00475     if (keyword == "accesslog") accesslog_ = value;
00476     else if (keyword == "autopurgejobs") autopurgejobs_ = (value.toLower() == "yes");
00477     else if (keyword == "browseaddress") browseaddresses_.append("Send " + value);
00478     else if (keyword == "browseallow") browseaddresses_.append("Allow " + value);
00479     else if (keyword == "browsedeny") browseaddresses_.append("Deny " + value);
00480     else if (keyword == "browseinterval") browseinterval_ = value.toInt();
00481     else if (keyword == "browseorder") browseorder_ = (value.toLower() == "deny,allow" ? ORDER_DENY_ALLOW : ORDER_ALLOW_DENY);
00482     else if (keyword == "browsepoll") browseaddresses_.append("Poll " + value);
00483     else if (keyword == "browseport") browseport_ = value.toInt();
00484     else if (keyword == "browseprotocols") {
00485         browseprotocols_.clear();
00486         QStringList prots = value.split(QRegExp("\\s"), QString::SkipEmptyParts);
00487         if (prots.contains("all"))
00488             browseprotocols_ << "CUPS" << "SLP";
00489         else
00490             for (QStringList::ConstIterator it = prots.begin(); it != prots.end(); ++it)
00491                 browseprotocols_ << (*it).toUpper();
00492     } else if (keyword == "browserelay") browseaddresses_.append("Relay " + value);
00493     else if (keyword == "browseshortnames") useshortnames_ = (value.toLower() != "no");
00494     else if (keyword == "browsetimeout") browsetimeout_ = value.toInt();
00495     else if (keyword == "browsing") browsing_ = (value.toLower() != "off");
00496     else if (keyword == "classification") {
00497         QString cl = value.toLower();
00498         if (cl == "none") classification_ = CLASS_NONE;
00499         else if (cl == "classified") classification_ = CLASS_CLASSIFIED;
00500         else if (cl == "confidential") classification_ = CLASS_CONFIDENTIAL;
00501         else if (cl == "secret") classification_ = CLASS_SECRET;
00502         else if (cl == "topsecret") classification_ = CLASS_TOPSECRET;
00503         else if (cl == "unclassified") classification_ = CLASS_UNCLASSIFIED;
00504         else {
00505             classification_ = CLASS_OTHER;
00506             otherclassname_ = cl;
00507         }
00508     } else if (keyword == "classifyoverride") classoverride_ = (value.toLower() == "yes");
00509     else if (keyword == "datadir") datadir_ = value;
00510     else if (keyword == "defaultcharset") charset_ = value;
00511     else if (keyword == "defaultlanguage") language_ = value;
00512     else if (keyword == "documentroot") documentdir_ = value;
00513     else if (keyword == "errorlog") errorlog_ = value;
00514     else if (keyword == "filterlimit") filterlimit_ = value.toInt();
00515     else if (keyword == "fontpath") fontpath_ += value.split(':', QString::SkipEmptyParts);
00516     else if (keyword == "group") group_ = value;
00517     else if (keyword == "hideimplicitmembers") hideimplicitmembers_ = (value.toLower() != "no");
00518     else if (keyword == "hostnamelookups") {
00519         QString h = value.toLower();
00520         if (h == "on") hostnamelookup_ = HOSTNAME_ON;
00521         else if (h == "double") hostnamelookup_ = HOSTNAME_DOUBLE;
00522         else hostnamelookup_ = HOSTNAME_OFF;
00523     } else if (keyword == "implicitclasses") useimplicitclasses_ = (value.toLower() != "off");
00524     else if (keyword == "implicitanyclasses") useanyclasses_ = (value.toLower() == "on");
00525     else if (keyword == "keepalive") keepalive_ = (value.toLower() != "off");
00526     else if (keyword == "keepalivetimeout") keepalivetimeout_ = value.toInt();
00527     else if (keyword == "listen") listenaddresses_.append("Listen " + value);
00528     else if (keyword == "loglevel") {
00529         QString ll = value.toLower();
00530         if (ll == "none") loglevel_ = LOGLEVEL_NONE;
00531         else if (ll == "error") loglevel_ = LOGLEVEL_ERROR;
00532         else if (ll == "warn") loglevel_ = LOGLEVEL_WARN;
00533         else if (ll == "info") loglevel_ = LOGLEVEL_INFO;
00534         else if (ll == "debug") loglevel_ = LOGLEVEL_DEBUG;
00535         else if (ll == "debug2") loglevel_ = LOGLEVEL_DEBUG2;
00536     } else if (keyword == "maxclients") maxclients_ = value.toInt();
00537     else if (keyword == "maxjobs") maxjobs_ = value.toInt();
00538     else if (keyword == "maxjobsperprinter") maxjobsperprinter_ = value.toInt();
00539     else if (keyword == "maxjobsperuser") maxjobsperuser_ = value.toInt();
00540     else if (keyword == "maxrequestsize") maxrequestsize_ = value;
00541     else if (keyword == "maxlogsize") maxlogsize_ = value;
00542     /*{
00543      // FIXME: support for suffixes
00544      int suffix;
00545      splitSizeSpec( value, maxlogsize_, suffix );
00546     }*/
00547     else if (keyword == "pagelog") pagelog_ = value;
00548     else if (keyword == "port") listenaddresses_.append("Listen *:" + value);
00549     else if (keyword == "preservejobhistory") keepjobhistory_ = (value != "off");
00550     else if (keyword == "preservejobfiles") keepjobfiles_ = (value == "on");
00551     else if (keyword == "printcap") printcap_ = value;
00552     else if (keyword == "printcapformat") printcapformat_ = (value.toLower() == "solaris" ? PRINTCAP_SOLARIS : PRINTCAP_BSD);
00553     else if (keyword == "requestroot") requestdir_ = value;
00554     else if (keyword == "remoteroot") remoteroot_ = value;
00555     else if (keyword == "ripcache") ripcache_ = value;
00556     else if (keyword == "serveradmin") serveradmin_ = value;
00557     else if (keyword == "serverbin") serverbin_ = value;
00558     else if (keyword == "servercertificate") encryptcert_ = value;
00559     else if (keyword == "serverkey") encryptkey_ = value;
00560     else if (keyword == "servername") servername_ = value;
00561     else if (keyword == "serverroot") serverfiles_ = value;
00562     else if (keyword == "ssllisten") listenaddresses_.append("SSLListen " + value);
00563     else if (keyword == "sslport") listenaddresses_.append("SSLListen *:" + value);
00564     else if (keyword == "systemgroup") systemgroup_ = value;
00565     else if (keyword == "tempdir") tmpfiles_ = value;
00566     else if (keyword == "timeout") clienttimeout_ = value.toInt();
00567     else if (keyword == "user") user_ = value;
00568     else {
00569         // unrecognized option
00570         unknown_ << QPair<QString, QString>(keyword, value);
00571     }
00572     return true;
00573 }
00574 
00575 bool CupsdConf::loadAvailableResources()
00576 {
00577     KConfigGroup conf = KSharedConfig::openConfig("kdeprintrc")->group("CUPS");
00578     QString host = conf.readEntry("Host", cupsServer());
00579     int  port = conf.readEntry("Port", ippPort());
00580     http_t *http_ = httpConnect(host.toLocal8Bit(), port);
00581 
00582     resources_.clear();
00583     // standard resources
00584     resources_.append(new CupsResource("/"));
00585     resources_.append(new CupsResource("/admin"));
00586     resources_.append(new CupsResource("/printers"));
00587     resources_.append(new CupsResource("/classes"));
00588     resources_.append(new CupsResource("/jobs"));
00589 
00590     if (!http_)
00591         return false;
00592 
00593     // printer resources
00594     ipp_t *request_ = ippNew();
00595     cups_lang_t* lang = cupsLangDefault();
00596     ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang));
00597     ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language);
00598     request_->request.op.operation_id = CUPS_GET_PRINTERS;
00599     request_ = cupsDoRequest(http_, request_, "/printers/");
00600     if (request_) {
00601         QString name;
00602         int type(0);
00603         ipp_attribute_t *attr = request_->attrs;
00604         while (attr) {
00605             // check new printer (keep only local non-implicit printers)
00606             if (!attr->name) {
00607                 if (!(type & CUPS_PRINTER_REMOTE) && !(type & CUPS_PRINTER_IMPLICIT) && !name.isEmpty())
00608                     resources_.append(new CupsResource("/printers/" + name));
00609                 name = "";
00610                 type = 0;
00611             } else if (strcmp(attr->name, "printer-name") == 0) name = attr->values[0].string.text;
00612             else if (strcmp(attr->name, "printer-type") == 0) type = attr->values[0].integer;
00613             attr = attr->next;
00614         }
00615         if (!(type & CUPS_PRINTER_REMOTE) && !(type & CUPS_PRINTER_IMPLICIT) && !name.isEmpty())
00616             resources_.append(new CupsResource("/printers/" + name));
00617         ippDelete(request_);
00618     }
00619     // class resources
00620     request_ = ippNew();
00621     ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang));
00622     ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language);
00623     request_->request.op.operation_id = CUPS_GET_CLASSES;
00624     request_ = cupsDoRequest(http_, request_, "/classes/");
00625     if (request_) {
00626         QString name;
00627         int type(0);
00628         ipp_attribute_t *attr = request_->attrs;
00629         while (attr) {
00630             // check new class (keep only local classes)
00631             if (!attr->name) {
00632                 if (!(type & CUPS_PRINTER_REMOTE) && !name.isEmpty())
00633                     resources_.append(new CupsResource("/classes/" + name));
00634                 name = "";
00635                 type = 0;
00636             } else if (strcmp(attr->name, "printer-name") == 0) name = attr->values[0].string.text;
00637             else if (strcmp(attr->name, "printer-type") == 0) type = attr->values[0].integer;
00638             attr = attr->next;
00639         }
00640         if (!(type & CUPS_PRINTER_REMOTE) && !name.isEmpty())
00641             resources_.append(new CupsResource("/classes/" + name));
00642         ippDelete(request_);
00643     }
00644     httpClose(http_);
00645     return true;
00646 }
00647 
00648 //------------------------------------------------------------------------------------------------
00649 
00650 CupsLocation::CupsLocation()
00651 {
00652     resource_ = 0;
00653     resourcename_ = "";
00654     authtype_ = AUTHTYPE_NONE;
00655     authclass_ = AUTHCLASS_ANONYMOUS;
00656     authname_.clear();
00657     encryption_ = ENCRYPT_IFREQUESTED;
00658     satisfy_ = SATISFY_ALL;
00659     order_ = ORDER_ALLOW_DENY;
00660     // addresses_
00661 }
00662 
00663 CupsLocation::CupsLocation(const CupsLocation& loc)
00664         : resource_(loc.resource_),
00665         resourcename_(loc.resourcename_),
00666         authtype_(loc.authtype_),
00667         authclass_(loc.authclass_),
00668         authname_(loc.authname_),
00669         encryption_(loc.encryption_),
00670         satisfy_(loc.satisfy_),
00671         order_(loc.order_),
00672         addresses_(loc.addresses_)
00673 {
00674 }
00675 
00676 bool CupsLocation::parseResource(const QString& line)
00677 {
00678     QString str = line.simplified();
00679     int p1 = line.indexOf(' '), p2 = line.indexOf('>');
00680     if (p1 != -1 && p2 != -1) {
00681         resourcename_ = str.mid(p1 + 1, p2 - p1 - 1);
00682         return true;
00683     } else return false;
00684 }
00685 
00686 bool CupsLocation::parseOption(const QString& line)
00687 {
00688     <