00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include "cupsdconf.h"
00022
00023 #include <qfile.h>
00024 #include <qregexp.h>
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <kconfig.h>
00028
00029 #include <stdlib.h>
00030 #include <cups/cups.h>
00031 #include <cups/ipp.h>
00032 #include <cups/language.h>
00033
00034 QString findDir(const QStringList& list)
00035 {
00036 for (QStringList::ConstIterator it=list.begin(); it!=list.end(); ++it)
00037 if (QFile::exists(*it))
00038 return *it;
00039
00040 return list[0];
00041 }
00042
00043 void splitSizeSpec(const QString& s, int& sz, int& suff)
00044 {
00045 int p = s.find(QRegExp("\\D"));
00046 sz = s.mid(0, p).toInt();
00047 if (p != -1)
00048 {
00049 switch (s[p].latin1())
00050 {
00051 case 'k': suff = UNIT_KB; break;
00052 default:
00053 case 'm': suff = UNIT_MB; break;
00054 case 'g': suff = UNIT_GB; break;
00055 case 't': suff = UNIT_TILE; break;
00056 }
00057 }
00058 else
00059 suff = UNIT_MB;
00060 }
00061
00062 CupsdConf::CupsdConf()
00063 {
00064
00065 datadir_ = findDir(QStringList("/usr/share/cups")
00066 << "/usr/local/share/cups"
00067 << "/opt/share/cups"
00068 << "/opt/local/share/cups");
00069 documentdir_ = findDir(QStringList(datadir_+"/doc")
00070 << datadir_.left(datadir_.length()-5)+"/doc/cups");
00071
00072 requestdir_ = findDir(QStringList("/var/spool/cups")
00073 << "/var/cups");
00074 serverbin_ = findDir(QStringList("/usr/lib" KDELIBSUFF "/cups")
00075 << "/usr/local/lib" KDELIBSUFF "/cups"
00076 << "/opt/lib" KDELIBSUFF "/cups"
00077 << "/opt/local/lib" KDELIBSUFF "/cups");
00078 serverfiles_ = findDir(QStringList("/etc/cups")
00079 << "/usr/local/etc/cups");
00080 tmpfiles_ = requestdir_+"/tmp";
00081
00082
00083 servername_ = QString::null;
00084 serveradmin_ = QString::null;
00085 classification_ = CLASS_NONE;
00086 otherclassname_ = QString::null;
00087 classoverride_ = false;
00088 charset_ = "utf-8";
00089 language_ = "en";
00090 printcap_ = "/etc/printcap";
00091 printcapformat_ = PRINTCAP_BSD;
00092 remoteroot_ = "remroot";
00093 systemgroup_ = "sys";
00094 encryptcert_ = serverfiles_+"/ssl/server.crt";
00095 encryptkey_ = serverfiles_+"/ssl/server.key";
00096 hostnamelookup_ = HOSTNAME_OFF;
00097 keepalive_ = true;
00098 keepalivetimeout_ = 60;
00099 maxclients_ = 100;
00100 maxrequestsize_ = "0";
00101 clienttimeout_ = 300;
00102
00103 QString logdir = findDir(QStringList("/var/log/cups")
00104 << "/var/spool/cups/log"
00105 << "/var/cups/log");
00106 accesslog_ = logdir+"/access_log";
00107 errorlog_ = logdir+"/error_log";
00108 pagelog_ = logdir+"/page_log";
00109 maxlogsize_ = "1m";
00110 loglevel_ = LOGLEVEL_INFO;
00111 keepjobhistory_ = true;
00112 keepjobfiles_ = false;
00113 autopurgejobs_ = false;
00114 maxjobs_ = 0;
00115 maxjobsperprinter_ = 0;
00116 maxjobsperuser_ = 0;
00117 user_ = "lp";
00118 group_ = "lp";
00119 ripcache_ = "8m";
00120 filterlimit_ = 0;
00121 browsing_ = true;
00122 browseprotocols_ << "CUPS";
00123 browseport_ = ippPort();
00124 browseinterval_ = 30;
00125 browsetimeout_ = 300;
00126
00127 browseorder_ = ORDER_ALLOW_DENY;
00128 useimplicitclasses_ = true;
00129 hideimplicitmembers_ = true;
00130 useshortnames_ = true;
00131 useanyclasses_ = false;
00132
00133 loadAvailableResources();
00134 }
00135
00136 CupsdConf::~CupsdConf()
00137 {
00138 }
00139
00140 bool CupsdConf::loadFromFile(const QString& filename)
00141 {
00142 QFile f(filename);
00143 if (!f.exists() || !f.open(IO_ReadOnly)) return false;
00144 else
00145 {
00146 QTextStream t(&f);
00147 QString line;
00148 bool done(false), value(true);
00149 while (!done && value)
00150 {
00151 line = t.readLine().simplifyWhiteSpace();
00152 if (line.isEmpty())
00153 {
00154 if (t.atEnd()) done = true;
00155 else continue;
00156 }
00157 else if (line[0] == '#') continue;
00158 else if (line.left(9).lower() == "<location")
00159 {
00160 CupsLocation *location = new CupsLocation();
00161 locations_.append(location);
00162 if (!location->parseResource(line) || !parseLocation(location, t))
00163 value = false;
00164
00165 for (resources_.first();resources_.current();resources_.next())
00166 if (resources_.current()->path_ == location->resourcename_)
00167 location->resource_ = resources_.current();
00168 }
00169 else value = parseOption(line);
00170 }
00171 f.close();
00172 return value;
00173 }
00174 }
00175
00176 bool CupsdConf::saveToFile(const QString& filename)
00177 {
00178 QFile f(filename);
00179 if (!f.open(IO_WriteOnly))
00180 return false;
00181 else
00182 {
00183 QTextStream t(&f);
00184 t << comments_["header"] << endl;
00185 t << "# Server" << endl << endl;
00186
00187 t << comments_["servername"] << endl;
00188 if ( !servername_.isEmpty() )
00189 t << "ServerName " << servername_ << endl;
00190
00191 t << endl << comments_["serveradmin"] << endl;
00192 if ( !serveradmin_.isEmpty() )
00193 t << "ServerAdmin " << serveradmin_ << endl;
00194
00195 t << endl << comments_["classification"] << endl;
00196 t << "Classification ";
00197 switch (classification_)
00198 {
00199 default:
00200 case CLASS_NONE: t << "none"; break;
00201 case CLASS_CLASSIFIED: t << "classified"; break;
00202 case CLASS_CONFIDENTIAL: t << "confidential"; break;
00203 case CLASS_SECRET: t << "secret"; break;
00204 case CLASS_TOPSECRET: t << "topsecret"; break;
00205 case CLASS_UNCLASSIFIED: t << "unclassified"; break;
00206 case CLASS_OTHER: t << otherclassname_; break;
00207 }
00208 t << endl;
00209
00210 t << endl << comments_["classifyoverride"] << endl;
00211 if (classification_ != CLASS_NONE) t << "ClassifyOverride " << (classoverride_ ? "Yes" : "No") << endl;
00212
00213 t << endl << comments_["defaultcharset"] << endl;
00214 t << "DefaultCharset " << charset_.upper() << endl;
00215
00216 t << endl << comments_["defaultlanguage"] << endl;
00217 t << "DefaultLanguage " << language_.lower() << endl;
00218
00219 t << endl << comments_["printcap"] << endl;
00220 t << "Printcap " << printcap_ << endl;
00221
00222 t << endl << comments_["printcapformat"] << endl;
00223 t << "PrintcapFormat " << (printcapformat_ == PRINTCAP_SOLARIS ? "Solaris" : "BSD") << endl;
00224
00225 t << endl << "# Security" << endl;
00226 t << endl << comments_["remoteroot"] << endl;
00227 t << "RemoteRoot " << remoteroot_ << endl;
00228
00229 t << endl << comments_["systemgroup"] << endl;
00230 t << "SystemGroup " << systemgroup_ << endl;
00231
00232 t << endl << comments_["servercertificate"] << endl;
00233 t << "ServerCertificate " << encryptcert_ << endl;
00234
00235 t << endl << comments_["serverkey"] << endl;
00236 t << "ServerKey " << encryptkey_ << endl;
00237
00238 t << endl << comments_["locations"] << endl;
00239 for (locations_.first(); locations_.current(); locations_.next())
00240 {
00241 CupsLocation *loc = locations_.current();
00242 t << "<Location " << loc->resourcename_ << ">" << endl;
00243 if (loc->authtype_ != AUTHTYPE_NONE)
00244 {
00245 t << "AuthType ";
00246 switch (loc->authtype_)
00247 {
00248 case AUTHTYPE_BASIC: t << "Basic"; break;
00249 case AUTHTYPE_DIGEST: t << "Digest"; break;
00250 }
00251 t << endl;
00252 }
00253 if (loc->authclass_ != AUTHCLASS_ANONYMOUS)
00254 {
00255 switch (loc->authclass_)
00256 {
00257 case AUTHCLASS_USER:
00258 if (!loc->authname_.isEmpty())
00259 t << "Require user " << loc->authname_ << endl;
00260 else
00261 t << "AuthClass User" << endl;
00262 break;
00263 case AUTHCLASS_GROUP:
00264 if (!loc->authname_.isEmpty())
00265 t << "Require group " << loc->authname_ << endl;
00266 else
00267 t << "AuthClass Group" << endl;
00268 break;
00269 case AUTHCLASS_SYSTEM:
00270 t << "AuthClass System" << endl;
00271 break;
00272 }
00273 }
00274 t << "Encryption ";
00275 switch (loc->encryption_)
00276 {
00277 case ENCRYPT_ALWAYS: t << "Always"; break;
00278 case ENCRYPT_NEVER: t << "Never"; break;
00279 case ENCRYPT_REQUIRED: t << "Required"; break;
00280 default:
00281 case ENCRYPT_IFREQUESTED: t << "IfRequested"; break;
00282 }
00283 t << endl;
00284 t << "Satisfy " << (loc->satisfy_ == SATISFY_ALL ? "All" : "Any") << endl;
00285 t << "Order " << (loc->order_ == ORDER_ALLOW_DENY ? "allow,deny" : "deny,allow") << endl;
00286 for (QStringList::ConstIterator it=loc->addresses_.begin(); it!=loc->addresses_.end(); ++it)
00287 t << *it << endl;
00288 t << "</Location>" << endl;
00289 }
00290
00291 t << endl << "# Network" << endl;
00292 t << endl << comments_["hostnamelookups"] << endl;
00293 t << "HostnameLookups ";
00294 switch (hostnamelookup_)
00295 {
00296 default:
00297 case HOSTNAME_OFF: t << "Off"; break;
00298 case HOSTNAME_ON: t << "On"; break;
00299 case HOSTNAME_DOUBLE: t << "Double"; break;
00300 }
00301 t << endl;
00302
00303 t << endl << comments_["keepalive"] << endl;
00304 t << "KeepAlive " << (keepalive_ ? "On" : "Off") << endl;
00305
00306 t << endl << comments_["keepalivetimeout"] << endl;
00307 t << "KeepAliveTimeout " << keepalivetimeout_ << endl;
00308
00309 t << endl << comments_["maxclients"] << endl;
00310 t << "MaxClients " << maxclients_ << endl;
00311
00312 t << endl << comments_["maxrequestsize"] << endl;
00313 t << "MaxRequestSize " << maxrequestsize_ << endl;
00314
00315 t << endl << comments_["timeout"] << endl;
00316 t << "Timeout " << clienttimeout_ << endl;
00317
00318 t << endl << comments_["listen"] << endl;
00319 for (QStringList::ConstIterator it=listenaddresses_.begin(); it!=listenaddresses_.end(); ++it)
00320 t << *it << endl;
00321
00322 t << endl << "# Log" << endl;
00323 t << endl << comments_["accesslog"] << endl;
00324 t << "AccessLog " << accesslog_ << endl;
00325
00326 t << endl << comments_["errorlog"] << endl;
00327 t << "ErrorLog " << errorlog_ << endl;
00328
00329 t << endl << comments_["pagelog"] << endl;
00330 t << "PageLog " << pagelog_ << endl;
00331
00332 t << endl << comments_["maxlogsize"] << endl;
00333
00334 t << "MaxLogSize " << maxlogsize_ << endl;
00335
00336 t << endl << comments_["loglevel"] << endl;
00337 t << "LogLevel ";
00338 switch (loglevel_)
00339 {
00340 case LOGLEVEL_NONE: t << "none"; break;
00341 default:
00342 case LOGLEVEL_INFO: t << "info"; break;
00343 case LOGLEVEL_ERROR: t << "error"; break;
00344 case LOGLEVEL_WARN: t << "warn"; break;
00345 case LOGLEVEL_DEBUG: t << "debug"; break;
00346 case LOGLEVEL_DEBUG2: t << "debug2"; break;
00347 }
00348 t << endl;
00349
00350 t << endl << "# Jobs" << endl;
00351 t << endl << comments_["preservejobhistory"] << endl;
00352 t << "PreserveJobHistory " << (keepjobhistory_ ? "On" : "Off") << endl;
00353
00354 t << endl << comments_["preservejobfiles"] << endl;
00355 if (keepjobhistory_) t << "PreserveJobFiles " << (keepjobfiles_ ? "On" : "Off") << endl;
00356
00357 t << endl << comments_["autopurgejobs"] << endl;
00358 if (keepjobhistory_) t << "AutoPurgeJobs " << (autopurgejobs_ ? "Yes" : "No") << endl;
00359
00360 t << endl << comments_["maxjobs"] << endl;
00361 t << "MaxJobs " << maxjobs_ << endl;
00362
00363 t << endl << comments_["maxjobsperprinter"] << endl;
00364 t << "MaxJobsPerPrinter " << maxjobsperprinter_ << endl;
00365
00366 t << endl << comments_["maxjobsperuser"] << endl;
00367 t << "MaxJobsPerUser " << maxjobsperuser_ << endl;
00368
00369 t << endl << "# Filter" << endl;
00370 t << endl << comments_["user"] << endl;
00371 t << "User " << user_ << endl;
00372
00373 t << endl << comments_["group"] << endl;
00374 t << "Group " << group_ << endl;
00375
00376 t << endl << comments_["ripcache"] << endl;
00377 t << "RIPCache " << ripcache_ << endl;
00378
00379 t << endl << comments_["filterlimit"] << endl;
00380 t << "FilterLimit " << filterlimit_ << endl;
00381
00382 t << endl << "# Directories" << endl;
00383 t << endl << comments_["datadir"] << endl;
00384 t << "DataDir " << datadir_ << endl;
00385
00386 t << endl << comments_["documentroot"] << endl;
00387 t << "DocumentRoot " << documentdir_ << endl;
00388
00389 t << endl << comments_["fontpath"] << endl;
00390 for (QStringList::ConstIterator it=fontpath_.begin(); it!=fontpath_.end(); ++it)
00391 t << "FontPath " << *it << endl;
00392
00393 t << endl << comments_["requestroot"] << endl;
00394 t << "RequestRoot " << requestdir_ << endl;
00395
00396 t << endl << comments_["serverbin"] << endl;
00397 t << "ServerBin " << serverbin_ << endl;
00398
00399 t << endl << comments_["serverroot"] << endl;
00400 t << "ServerRoot " << serverfiles_ << endl;
00401
00402 t << endl << comments_["tempdir"] << endl;
00403 t << "TempDir " << tmpfiles_ << endl;
00404
00405 t << endl << "# Browsing" << endl;
00406 t << endl << comments_["browsing"] << endl;
00407 t << "Browsing " << (browsing_ ? "On" : "Off") << endl;
00408
00409 t << endl << comments_["browseprotocols"] << endl;
00410 if (browsing_)
00411 {
00412 t << "BrowseProtocols ";
00413 for (QStringList::ConstIterator it=browseprotocols_.begin(); it!=browseprotocols_.end(); ++it)
00414 t << (*it).upper() << " ";
00415 t << endl;
00416 }
00417
00418 t << endl << comments_["browseport"] << endl;
00419 if (browsing_) t << "BrowsePort " << browseport_ << endl;
00420
00421 t << endl << comments_["browseinterval"] << endl;
00422 if (browsing_) t << "BrowseInterval " << browseinterval_ << endl;
00423
00424 t << endl << comments_["browsetimeout"] << endl;
00425 if (browsing_) t << "BrowseTimeout " << browsetimeout_ << endl;
00426
00427 t << endl << comments_["browseaddress"] << endl;
00428 if (browsing_)
00429 for (QStringList::ConstIterator it=browseaddresses_.begin(); it!=browseaddresses_.end(); ++it)
00430 if ((*it).startsWith("Send"))
00431 t << "BrowseAddress " << (*it).mid(5) << endl;
00432 else
00433 t << "Browse" << (*it) << endl;
00434
00435 t << endl << comments_["browseorder"] << endl;
00436 if (browsing_) t << "BrowseOrder " << (browseorder_ == ORDER_ALLOW_DENY ? "allow,deny" : "deny,allow") << endl;
00437
00438 t << endl << comments_["implicitclasses"] << endl;
00439 if (browsing_) t << "ImplicitClasses " << (useimplicitclasses_ ? "On" : "Off") << endl;
00440
00441 t << endl << comments_["implicitanyclasses"] << endl;
00442 if (browsing_) t << "ImplicitAnyClasses " << (useanyclasses_ ? "On" : "Off") << endl;
00443
00444 t << endl << comments_["hideimplicitmembers"] << endl;
00445 if (browsing_) t << "HideImplicitMembers " << (hideimplicitmembers_ ? "Yes" : "No") << endl;
00446
00447 t << endl << comments_["browseshortnames"] << endl;
00448 if (browsing_) t << "BrowseShortNames " << (useshortnames_ ? "Yes" : "No") << endl;
00449
00450 t << endl << "# Unknown" << endl;
00451 for (QValueList< QPair<QString,QString> >::ConstIterator it=unknown_.begin(); it!=unknown_.end(); ++it)
00452 t << (*it).first << " " << (*it).second << endl;
00453
00454 return true;
00455 }
00456 }
00457
00458 bool CupsdConf::parseLocation(CupsLocation *location, QTextStream& file)
00459 {
00460 QString line;
00461 bool done(false);
00462 bool value(true);
00463 while (!done && value)
00464 {
00465 line = file.readLine().simplifyWhiteSpace();
00466 if (line.isEmpty())
00467 {
00468 if (file.atEnd())
00469 {
00470 value = false;
00471 done = true;
00472 }
00473 else continue;
00474 }
00475 else if (line[0] == '#') continue;
00476 else if (line.lower() == "</location>") done = true;
00477 else value = location->parseOption(line);
00478 }
00479 return value;
00480 }
00481
00482 bool CupsdConf::parseOption(const QString& line)
00483 {
00484 int p(-1);
00485 QString keyword, value, l(line.simplifyWhiteSpace());
00486
00487 if ((p=l.find(' ')) != -1)
00488 {
00489 keyword = l.left(p).lower();
00490 value = l.mid(p+1);
00491 }
00492 else
00493 {
00494 keyword = l.lower();
00495 }
00496
00497
00498 if (keyword == "accesslog") accesslog_ = value;
00499 else if (keyword == "autopurgejobs") autopurgejobs_ = (value.lower() == "yes");
00500 else if (keyword == "browseaddress") browseaddresses_.append("Send "+value);
00501 else if (keyword == "browseallow") browseaddresses_.append("Allow "+value);
00502 else if (keyword == "browsedeny") browseaddresses_.append("Deny "+value);
00503 else if (keyword == "browseinterval") browseinterval_ = value.toInt();
00504 else if (keyword == "browseorder") browseorder_ = (value.lower() == "deny,allow" ? ORDER_DENY_ALLOW : ORDER_ALLOW_DENY);
00505 else if (keyword == "browsepoll") browseaddresses_.append("Poll "+value);
00506 else if (keyword == "browseport") browseport_ = value.toInt();
00507 else if (keyword == "browseprotocols")
00508 {
00509 browseprotocols_.clear();
00510 QStringList prots = QStringList::split(QRegExp("\\s"), value, false);
00511 if (prots.find("all") != prots.end())
00512 browseprotocols_ << "CUPS" << "SLP";
00513 else
00514 for (QStringList::ConstIterator it=prots.begin(); it!=prots.end(); ++it)
00515 browseprotocols_ << (*it).upper();
00516 }
00517 else if (keyword == "browserelay") browseaddresses_.append("Relay "+value);
00518 else if (keyword == "browseshortnames") useshortnames_ = (value.lower() != "no");
00519 else if (keyword == "browsetimeout") browsetimeout_ = value.toInt();
00520 else if (keyword == "browsing") browsing_ = (value.lower() != "off");
00521 else if (keyword == "classification")
00522 {
00523 QString cl = value.lower();
00524 if (cl == "none") classification_ = CLASS_NONE;
00525 else if (cl == "classified") classification_ = CLASS_CLASSIFIED;
00526 else if (cl == "confidential") classification_ = CLASS_CONFIDENTIAL;
00527 else if (cl == "secret") classification_ = CLASS_SECRET;
00528 else if (cl == "topsecret") classification_ = CLASS_TOPSECRET;
00529 else if (cl == "unclassified") classification_ = CLASS_UNCLASSIFIED;
00530 else
00531 {
00532 classification_ = CLASS_OTHER;
00533 otherclassname_ = cl;
00534 }
00535 }
00536 else if (keyword == "classifyoverride") classoverride_ = (value.lower() == "yes");
00537 else if (keyword == "datadir") datadir_ = value;
00538 else if (keyword == "defaultcharset") charset_ = value;
00539 else if (keyword == "defaultlanguage") language_ = value;
00540 else if (keyword == "documentroot") documentdir_ = value;
00541 else if (keyword == "errorlog") errorlog_ = value;
00542 else if (keyword == "filterlimit") filterlimit_ = value.toInt();
00543 else if (keyword == "fontpath") fontpath_ += QStringList::split(':', value, false);
00544 else if (keyword == "group") group_ = value;
00545 else if (keyword == "hideimplicitmembers") hideimplicitmembers_ = (value.lower() != "no");
00546 else if (keyword == "hostnamelookups")
00547 {
00548 QString h = value.lower();
00549 if (h == "on") hostnamelookup_ = HOSTNAME_ON;
00550 else if (h == "double") hostnamelookup_ = HOSTNAME_DOUBLE;
00551 else hostnamelookup_ = HOSTNAME_OFF;
00552 }
00553 else if (keyword == "implicitclasses") useimplicitclasses_ = (value.lower() != "off");
00554 else if (keyword == "implicitanyclasses") useanyclasses_ = (value.lower() == "on");
00555 else if (keyword == "keepalive") keepalive_ = (value.lower() != "off");
00556 else if (keyword == "keepalivetimeout") keepalivetimeout_ = value.toInt();
00557 else if (keyword == "listen") listenaddresses_.append("Listen "+value);
00558 else if (keyword == "loglevel")
00559 {
00560 QString ll = value.lower();
00561 if (ll == "none") loglevel_ = LOGLEVEL_NONE;
00562 else if (ll == "error") loglevel_ = LOGLEVEL_ERROR;
00563 else if (ll == "warn") loglevel_ = LOGLEVEL_WARN;
00564 else if (ll == "info") loglevel_ = LOGLEVEL_INFO;
00565 else if (ll == "debug") loglevel_ = LOGLEVEL_DEBUG;
00566 else if (ll == "debug2") loglevel_ = LOGLEVEL_DEBUG2;
00567 }
00568 else if (keyword == "maxclients") maxclients_ = value.toInt();
00569 else if (keyword == "maxjobs") maxjobs_ = value.toInt();
00570 else if (keyword == "maxjobsperprinter") maxjobsperprinter_ = value.toInt();
00571 else if (keyword == "maxjobsperuser") maxjobsperuser_ = value.toInt();
00572 else if (keyword == "maxrequestsize") maxrequestsize_ = value;
00573 else if (keyword == "maxlogsize") maxlogsize_ = value;
00574
00575
00576
00577
00578
00579 else if (keyword == "pagelog") pagelog_ = value;
00580 else if (keyword == "port") listenaddresses_.append("Listen *:"+value);
00581 else if (keyword == "preservejobhistory") keepjobhistory_ = (value != "off");
00582 else if (keyword == "preservejobfiles") keepjobfiles_ = (value == "on");
00583 else if (keyword == "printcap") printcap_ = value;
00584 else if (keyword == "printcapformat") printcapformat_ = (value.lower() == "solaris" ? PRINTCAP_SOLARIS : PRINTCAP_BSD);
00585 else if (keyword == "requestroot") requestdir_ = value;
00586 else if (keyword == "remoteroot") remoteroot_ = value;
00587 else if (keyword == "ripcache") ripcache_ = value;
00588 else if (keyword == "serveradmin") serveradmin_ = value;
00589 else if (keyword == "serverbin") serverbin_ = value;
00590 else if (keyword == "servercertificate") encryptcert_ = value;
00591 else if (keyword == "serverkey") encryptkey_ = value;
00592 else if (keyword == "servername") servername_ = value;
00593 else if (keyword == "serverroot") serverfiles_ = value;
00594 else if (keyword == "ssllisten") listenaddresses_.append("SSLListen "+value);
00595 else if (keyword == "sslport") listenaddresses_.append("SSLListen *:"+value);
00596 else if (keyword == "systemgroup") systemgroup_ = value;
00597 else if (keyword == "tempdir") tmpfiles_ = value;
00598 else if (keyword == "timeout") clienttimeout_ = value.toInt();
00599 else if (keyword == "user") user_ = value;
00600 else
00601 {
00602
00603 unknown_ << QPair<QString,QString>(keyword, value);
00604 }
00605 return true;
00606 }
00607
00608 bool CupsdConf::loadAvailableResources()
00609 {
00610 KConfig conf("kdeprintrc");
00611 conf.setGroup("CUPS");
00612 QString host = conf.readEntry("Host",cupsServer());
00613 int port = conf.readNumEntry("Port",ippPort());
00614 http_t *http_ = httpConnect(host.local8Bit(),port);
00615
00616 resources_.clear();
00617
00618 resources_.append(new CupsResource("/"));
00619 resources_.append(new CupsResource("/admin"));
00620 resources_.append(new CupsResource("/printers"));
00621 resources_.append(new CupsResource("/classes"));
00622 resources_.append(new CupsResource("/jobs"));
00623
00624 if (!http_)
00625 return false;
00626
00627
00628 ipp_t *request_ = ippNew();
00629 cups_lang_t* lang = cupsLangDefault();
00630 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang));
00631 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language);
00632 request_->request.op.operation_id = CUPS_GET_PRINTERS;
00633 request_ = cupsDoRequest(http_, request_, "/printers/");
00634 if (request_)
00635 {
00636 QString name;
00637 int type(0);
00638 ipp_attribute_t *attr = request_->attrs;
00639 while (attr)
00640 {
00641
00642 if (!attr->name)
00643 {
00644 if (!(type & CUPS_PRINTER_REMOTE) && !(type & CUPS_PRINTER_IMPLICIT) && !name.isEmpty())
00645 resources_.append(new CupsResource("/printers/"+name));
00646 name = "";
00647 type = 0;
00648 }
00649 else if (strcmp(attr->name, "printer-name") == 0) name = attr->values[0].string.text;
00650 else if (strcmp(attr->name, "printer-type") == 0) type = attr->values[0].integer;
00651 attr = attr->next;
00652 }
00653 if (!(type & CUPS_PRINTER_REMOTE) && !(type & CUPS_PRINTER_IMPLICIT) && !name.isEmpty())
00654 resources_.append(new CupsResource("/printers/"+name));
00655 ippDelete(request_);
00656 }
00657
00658 request_ = ippNew();
00659 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang));
00660 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language);
00661 request_->request.op.operation_id = CUPS_GET_CLASSES;
00662 request_ = cupsDoRequest(http_, request_, "/classes/");
00663 if (request_)
00664 {
00665 QString name;
00666 int type(0);
00667 ipp_attribute_t *attr = request_->attrs;
00668 while (attr)
00669 {
00670
00671 if (!attr->name)
00672 {
00673 if (!(type & CUPS_PRINTER_REMOTE) && !name.isEmpty())
00674 resources_.append(new CupsResource("/classes/"+name));
00675 name = "";
00676 type = 0;
00677 }
00678 else if (strcmp(attr->name, "printer-name") == 0) name = attr->values[0].string.text;
00679 else if (strcmp(attr->name, "printer-type") == 0) type = attr->values[0].integer;
00680 attr = attr->next;
00681 }
00682 if (!(type & CUPS_PRINTER_REMOTE) && !name.isEmpty())
00683 resources_.append(new CupsResource("/classes/"+name));
00684 ippDelete(request_);
00685 }
00686 httpClose(http_);
00687 return true;
00688 }
00689
00690
00691
00692 CupsLocation::CupsLocation()
00693 {
00694 resource_ = 0;
00695 resourcename_ = "";
00696 authtype_ = AUTHTYPE_NONE;
00697 authclass_ = AUTHCLASS_ANONYMOUS;
00698 authname_ = QString::null;
00699 encryption_ = ENCRYPT_IFREQUESTED;
00700 satisfy_ = SATISFY_ALL;
00701 order_ = ORDER_ALLOW_DENY;
00702
00703 }
00704
00705 CupsLocation::CupsLocation(const CupsLocation& loc)
00706 : resource_(loc.resource_),
00707 resourcename_(loc.resourcename_),
00708 authtype_(loc.authtype_),
00709 authclass_(loc.authclass_),
00710 authname_(loc.authname_),
00711 encryption_(loc.encryption_),
00712 satisfy_(loc.satisfy_),
00713 order_(loc.order_),
00714 addresses_(loc.addresses_)
00715 {
00716 }
00717
00718 bool CupsLocation::parseResource(const QString& line)
00719 {
00720 QString str = line.simplifyWhiteSpace();
00721 int p1 = line.find(' '), p2 = line.find('>');
00722 if (p1 != -1 && p2 != -1)
00723 {
00724 resourcename_ = str.mid(p1+1,p2-p1-1);
00725 return true;
00726 }
00727 else return false;
00728 }
00729
00730 bool CupsLocation::parseOption(const QString& line)
00731 {
00732 int p(-1);
00733 QString keyword, value, l(line.simplifyWhiteSpace());
00734
00735 if ((p=l.find(' ')) != -1)
00736 {
00737 keyword = l.left(p).lower();
00738 value = l.mid(p+1);
00739 }
00740 else
00741 {
00742 keyword = l.lower();
00743 }
00744
00745 if (keyword == "authtype")
00746 {
00747 QString a = value.lower();
00748 if (a == "basic") authtype_ = AUTHTYPE_BASIC;
00749 else if (a == "digest") authtype_ = AUTHTYPE_DIGEST;
00750 else authtype_ = AUTHTYPE_NONE;
00751 }
00752 else if (keyword == "authclass")
00753 {
00754 QString a = value.lower();
00755 if (a == "user") authclass_ = AUTHCLASS_USER;
00756 else if (a == "system") authclass_ = AUTHCLASS_SYSTEM;
00757 else if (a == "group") authclass_ = AUTHCLASS_GROUP;
00758 else authclass_ = AUTHCLASS_ANONYMOUS;
00759 }
00760 else if (keyword == "authgroupname") authname_ = value;
00761 else if (keyword == "require")
00762 {
00763 int p = value.find(' ');
00764 if (p != -1)
00765 {
00766 authname_ = value.mid(p+1);
00767 QString cl = value.left(p).lower();
00768 if (cl == "user")
00769 authclass_ = AUTHCLASS_USER;
00770 else if (cl == "group")
00771 authclass_ = AUTHCLASS_GROUP;
00772 }
00773 }
00774 else if (keyword == "allow") addresses_.append("Allow "+value);
00775 else if (keyword == "deny") addresses_.append("Deny "+value);
00776 else if (keyword == "order") order_ = (value.lower() == "deny,allow" ? ORDER_DENY_ALLOW : ORDER_ALLOW_DENY);
00777 else if (keyword == "encryption")
00778 {
00779 QString e = value.lower();
00780 if (e == "always") encryption_ = ENCRYPT_ALWAYS;
00781 else if (e == "never") encryption_ = ENCRYPT_NEVER;
00782 else if (e == "required") encryption_ = ENCRYPT_REQUIRED;
00783 else encryption_ = ENCRYPT_IFREQUESTED;
00784 }
00785 else if (keyword == "satisfy") satisfy_ = (value.lower() == "any" ? SATISFY_ANY : SATISFY_ALL);
00786 else return false;
00787 return true;
00788 }
00789
00790
00791
00792 CupsResource::CupsResource()
00793 {
00794 type_ = RESOURCE_GLOBAL;
00795 }
00796
00797 CupsResource::CupsResource(const QString& path)
00798 {
00799 setPath(path);
00800 }
00801
00802 void CupsResource::setPath(const QString& path)
00803 {
00804 path_ = path;
00805 type_ = typeFromPath(path_);
00806 text_ = pathToText(path_);
00807 }
00808
00809 int CupsResource::typeFromText(const QString& text)
00810 {
00811 if (text == i18n("Base", "Root") || text == i18n("All printers") || text == i18n("All classes") || text == i18n("Print jobs")) return RESOURCE_GLOBAL;
00812 else if (text == i18n("Administration")) return RESOURCE_ADMIN;
00813 else if (text.find(i18n("Class")) == 0) return RESOURCE_CLASS;
00814 else if (text.find(i18n("Printer")) == 0) return RESOURCE_PRINTER;
00815 else return RESOURCE_PRINTER;
00816 }
00817
00818 int CupsResource::typeFromPath(const QString& path)
00819 {
00820 if (path == "/admin") return RESOURCE_ADMIN;
00821 else if (path == "/printers" || path == "/classes" || path == "/" || path == "/jobs") return RESOURCE_GLOBAL;
00822 else if (path.left(9) == "/printers") return RESOURCE_PRINTER;
00823 else if (path.left(8) == "/classes") return RESOURCE_CLASS;
00824 else return RESOURCE_GLOBAL;
00825 }
00826
00827 QString CupsResource::textToPath(const QString& text)
00828 {
00829 QString path("/");
00830 if (text == i18n("Administration")) path = "/admin";
00831 else if (text == i18n("All printers")) path = "/printers";
00832 else if (text == i18n("All classes")) path = "/classes";
00833 else if (text == i18n("Print jobs")) path = "/jobs";
00834 else if (text == i18n("Base", "Root")) path = "/";
00835 else if (text.find(i18n("Printer")) == 0)
00836 {
00837 path = "/printers/";
00838 path.append(text.right(text.length()-i18n("Printer").length()-1));
00839 }
00840 else if (text.find(i18n("Class")) == 0)
00841 {
00842 path = "/classes/";
00843 path.append(text.right(text.length()-i18n("Class").length()-1));
00844 }
00845 return path;
00846 }
00847
00848 QString CupsResource::pathToText(const QString& path)
00849 {
00850 QString text(i18n("Base", "Root"));
00851 if (path == "/admin") text = i18n("Administration");
00852 else if (path == "/printers") text = i18n("All printers");
00853 else if (path == "/classes") text = i18n("All classes");
00854 else if (path == "/") text = i18n("Root");
00855 else if (path == "/jobs") text = i18n("Print jobs");
00856 else if (path.find("/printers/") == 0)
00857 {
00858 text = i18n("Printer");
00859 text.append(" ");
00860 text.append(path.right(path.length()-10));
00861 }
00862 else if (path.find("/classes/") == 0)
00863 {
00864 text = i18n("Class");
00865 text.append(" ");
00866 text.append(path.right(path.length()-9));
00867 }
00868 return text;
00869 }
00870
00871 QString CupsResource::typeToIconName(int type)
00872 {
00873 switch (type)
00874 {
00875 case RESOURCE_ADMIN:
00876 case RESOURCE_GLOBAL:
00877 return QString("folder");
00878 case RESOURCE_PRINTER:
00879 return QString("kdeprint_printer");
00880 case RESOURCE_CLASS:
00881 return QString("kdeprint_printer_class");
00882 }
00883 return QString("folder");
00884 }