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