kdeprint Library API Documentation

apshandler.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., 59 Temple Place - Suite 330, 00017 * Boston, MA 02111-1307, USA. 00018 **/ 00019 00020 #include "apshandler.h" 00021 #include "driver.h" 00022 #include "printcapentry.h" 00023 #include "kmprinter.h" 00024 #include "lprsettings.h" 00025 #include "kmmanager.h" 00026 #include "util.h" 00027 #include "kprinter.h" 00028 00029 #include <qfile.h> 00030 #include <qdir.h> 00031 #include <qtextstream.h> 00032 #include <qvaluestack.h> 00033 #include <kstandarddirs.h> 00034 #include <klocale.h> 00035 #include <kdebug.h> 00036 00037 #include <sys/types.h> 00038 #include <sys/stat.h> 00039 00040 ApsHandler::ApsHandler(KMManager *mgr) 00041 : LprHandler("apsfilter", mgr) 00042 { 00043 m_counter = 1; 00044 } 00045 00046 bool ApsHandler::validate(PrintcapEntry *entry) 00047 { 00048 return (entry->field("if").right(9) == "apsfilter"); 00049 } 00050 00051 KMPrinter* ApsHandler::createPrinter(PrintcapEntry *entry) 00052 { 00053 entry->comment = QString::fromLatin1("# APS%1_BEGIN:printer%2").arg(m_counter).arg(m_counter); 00054 entry->postcomment = QString::fromLatin1("# APS%1_END - don't delete this").arg(m_counter); 00055 m_counter++; 00056 return LprHandler::createPrinter(entry); 00057 } 00058 00059 bool ApsHandler::completePrinter(KMPrinter *prt, PrintcapEntry *entry, bool shortmode) 00060 { 00061 if (LprHandler::completePrinter(prt, entry, shortmode)) 00062 { 00063 if (!shortmode) 00064 { 00065 QMap<QString,QString> opts = loadResources(entry); 00066 if (opts.contains("PRINTER")) 00067 { 00068 prt->setDescription(i18n("APS Driver (%1)").arg(opts["PRINTER"])); 00069 prt->setDriverInfo(prt->description()); 00070 } 00071 } 00072 if (prt->device().isEmpty()) 00073 { 00074 QString prot; 00075 QString smbname(sysconfDir() + "/" + prt->printerName() + "/smbclient.conf"); 00076 QString ncpname(sysconfDir() + "/" + prt->printerName() + "/netware.conf"); 00077 if (QFile::exists(smbname)) 00078 { 00079 QMap<QString,QString> opts = loadVarFile(smbname); 00080 if (opts.count() == 0) 00081 prt->setDevice("smb://<unknown>/<unknown>"); 00082 else 00083 { 00084 prt->setDevice(buildSmbURI( 00085 opts[ "SMB_WORKGROUP" ], 00086 opts[ "SMB_SERVER" ], 00087 opts[ "SMB_PRINTER" ], 00088 opts[ "SMB_USER" ], 00089 opts[ "SMB_PASSWD" ] ) ); 00090 } 00091 prot = "smb"; 00092 } 00093 else if (QFile::exists(ncpname)) 00094 { 00095 QMap<QString,QString> opts = loadVarFile(ncpname); 00096 if (opts.count() == 0) 00097 prt->setDevice("ncp://<unknown>/<unknown>"); 00098 else 00099 { 00100 QString uri = buildSmbURI( 00101 QString::null, 00102 opts[ "NCP_SERVER" ], 00103 opts[ "NCP_PRINTER" ], 00104 opts[ "NCP_USER" ], 00105 opts[ "NCP_PASSWD" ] ); 00106 uri.replace( 0, 3, "ncp" ); 00107 prt->setDevice(uri); 00108 } 00109 prot = "ncp"; 00110 } 00111 if (!prt->device().isEmpty()) 00112 prt->setLocation(i18n("Network printer (%1)").arg(prot)); 00113 } 00114 return true; 00115 } 00116 return false; 00117 } 00118 00119 QString ApsHandler::sysconfDir() 00120 { 00121 return QFile::encodeName("/etc/apsfilter"); 00122 } 00123 00124 QString ApsHandler::shareDir() 00125 { 00126 return driverDirectory(); 00127 } 00128 00129 QString ApsHandler::driverDirInternal() 00130 { 00131 return locateDir("apsfilter/setup", "/usr/share:/usr/local/share:/opt/share"); 00132 } 00133 00134 QMap<QString,QString> ApsHandler::loadResources(PrintcapEntry *entry) 00135 { 00136 return loadVarFile(sysconfDir() + "/" + (entry ? entry->name : QString::null) + "/apsfilterrc"); 00137 } 00138 00139 QMap<QString,QString> ApsHandler::loadVarFile(const QString& filename) 00140 { 00141 QMap<QString,QString> opts; 00142 QFile f(filename); 00143 if (f.open(IO_ReadOnly)) 00144 { 00145 QTextStream t(&f); 00146 QString line; 00147 int p(-1); 00148 while (!t.atEnd()) 00149 { 00150 line = t.readLine().stripWhiteSpace(); 00151 if (line.isEmpty() || line[0] == '#' || (p = line.find('=')) == -1) 00152 continue; 00153 QString variable = line.left(p).stripWhiteSpace(); 00154 QString value = line.mid(p+1).stripWhiteSpace(); 00155 if (!value.isEmpty() && value[0] == '\'') 00156 value = value.mid(1, value.length()-2); 00157 opts[variable] = value; 00158 } 00159 } 00160 return opts; 00161 } 00162 00163 DrMain* ApsHandler::loadDriver(KMPrinter *prt, PrintcapEntry *entry, bool config) 00164 { 00165 DrMain *driver = loadApsDriver(config); 00166 if (driver /* && config */ ) // Load resources in all case, to get the correct page size 00167 { 00168 QMap<QString,QString> opts = loadResources(entry); 00169 if ( !config && opts.contains( "PAPERSIZE" ) ) 00170 { 00171 // this is needed to keep applications informed 00172 // about the current selected page size 00173 opts[ "PageSize" ] = opts[ "PAPERSIZE" ]; 00174 00175 // default page size needs to be set to the actual 00176 // value of the printer driver, otherwise it's blocked 00177 // to A4 00178 DrBase *opt = driver->findOption( "PageSize" ); 00179 if ( opt ) 00180 opt->set( "default", opts[ "PageSize" ] ); 00181 } 00182 driver->setOptions(opts); 00183 driver->set("gsdriver", opts["PRINTER"]); 00184 } 00185 return driver; 00186 } 00187 00188 DrMain* ApsHandler::loadDbDriver(const QString& s) 00189 { 00190 int p = s.find('/'); 00191 DrMain *driver = loadApsDriver(true); 00192 if (driver) 00193 driver->set("gsdriver", s.mid(p+1)); 00194 return driver; 00195 } 00196 00197 DrMain* ApsHandler::loadApsDriver(bool config) 00198 { 00199 DrMain *driver = loadToolDriver(locate("data", (config ? "kdeprint/apsdriver1" : "kdeprint/apsdriver2"))); 00200 if (driver) 00201 driver->set("text", "APS Common Driver"); 00202 return driver; 00203 } 00204 00205 void ApsHandler::reset() 00206 { 00207 m_counter = 1; 00208 } 00209 00210 PrintcapEntry* ApsHandler::createEntry(KMPrinter *prt) 00211 { 00212 QString prot = prt->deviceProtocol(); 00213 if (prot != "parallel" && prot != "lpd" && prot != "smb" && prot != "ncp") 00214 { 00215 manager()->setErrorMsg(i18n("Unsupported backend: %1.").arg(prot)); 00216 return NULL; 00217 } 00218 QString path = sysconfDir() + "/" + prt->printerName(); 00219 if (!KStandardDirs::makeDir(path, 0755)) 00220 { 00221 manager()->setErrorMsg(i18n("Unable to create directory %1.").arg(path)); 00222 return NULL; 00223 } 00224 if (prot == "smb" || prot == "ncp") 00225 { 00226 // either "smb" or "ncp" 00227 QFile::remove(path + "/smbclient.conf"); 00228 QFile::remove(path + "/netware.conf"); 00229 QFile f; 00230 if (prot == "smb") 00231 { 00232 f.setName(path + "/smbclient.conf"); 00233 if (f.open(IO_WriteOnly)) 00234 { 00235 QTextStream t(&f); 00236 QString work, server, printer, user, passwd; 00237 if ( splitSmbURI( prt->device(), work, server, printer, user, passwd ) ) 00238 { 00239 if (work.isEmpty()) 00240 { 00241 manager()->setErrorMsg(i18n("Missing element: %1.").arg("Workgroup")); 00242 return NULL; 00243 } 00244 t << "SMB_SERVER='" << server << "'" << endl; 00245 t << "SMB_PRINTER='" << printer << "'" << endl; 00246 t << "SMB_IP=''" << endl; 00247 t << "SMB_WORKGROUP='" << work << "'" << endl; 00248 t << "SMB_BUFFER=1400" << endl; 00249 t << "SMB_FLAGS='-N'" << endl; 00250 if (!user.isEmpty()) 00251 { 00252 t << "SMB_USER='" << user << "'" << endl; 00253 t << "SMB_PASSWD='" << passwd << "'" << endl; 00254 } 00255 } 00256 else 00257 { 00258 manager()->setErrorMsg( i18n( "Invalid printer backend specification: %1" ).arg( prt->device() ) ); 00259 return NULL; 00260 } 00261 } 00262 else 00263 { 00264 manager()->setErrorMsg(i18n("Unable to create the file %1.").arg(f.name())); 00265 return NULL; 00266 } 00267 } 00268 else 00269 { 00270 f.setName(path + "/netware.conf"); 00271 if (f.open(IO_WriteOnly)) 00272 { 00273 QString work, server, printer, user, passwd; 00274 QString uri = prt->device(); 00275 uri.replace( 0, 3, "smb" ); 00276 if ( splitSmbURI( uri, work, server, printer, user, passwd ) ) 00277 { 00278 QTextStream t(&f); 00279 t << "NCP_SERVER='" << server << "'" << endl; 00280 t << "NCP_PRINTER='" << printer << "'" << endl; 00281 if (!user.isEmpty()) 00282 { 00283 t << "NCP_USER='" << user << "'" << endl; 00284 t << "NCP_PASSWD='" << passwd << "'" << endl; 00285 } 00286 } 00287 else 00288 { 00289 manager()->setErrorMsg( i18n( "Invalid printer backend specification: %1" ).arg( prt->device() ) ); 00290 return NULL; 00291 } 00292 } 00293 else 00294 { 00295 manager()->setErrorMsg(i18n("Unable to create the file %1.").arg(f.name())); 00296 return NULL; 00297 } 00298 } 00299 // change file permissions 00300 ::chmod(QFile::encodeName(f.name()).data(), S_IRUSR|S_IWUSR); 00301 } 00302 PrintcapEntry *entry = LprHandler::createEntry(prt); 00303 if (!entry) 00304 { 00305 entry = new PrintcapEntry; 00306 entry->addField("lp", Field::String, "/dev/null"); 00307 } 00308 QString sd = LprSettings::self()->baseSpoolDir() + "/" + prt->printerName(); 00309 entry->addField("af", Field::String, sd + "/acct"); 00310 entry->addField("lf", Field::String, sd + "/log"); 00311 entry->addField("if", Field::String, sysconfDir() + "/basedir/bin/apsfilter"); 00312 entry->comment = QString::fromLatin1("# APS%1_BEGIN:printer%2").arg(m_counter).arg(m_counter); 00313 entry->postcomment = QString::fromLatin1("# APS%1_END").arg(m_counter); 00314 m_counter++; 00315 return entry; 00316 } 00317 00318 bool ApsHandler::savePrinterDriver(KMPrinter *prt, PrintcapEntry *entry, DrMain *driver, bool*) 00319 { 00320 if (driver->get("gsdriver").isEmpty()) 00321 { 00322 manager()->setErrorMsg(i18n("The APS driver is not defined.")); 00323 return false; 00324 } 00325 QFile f(sysconfDir() + "/" + prt->printerName() + "/apsfilterrc"); 00326 if (f.open(IO_WriteOnly)) 00327 { 00328 QTextStream t(&f); 00329 t << "# File generated by KDEPrint" << endl; 00330 t << "PRINTER='" << driver->get("gsdriver") << "'" << endl; 00331 QValueStack<DrGroup*> stack; 00332 stack.push(driver); 00333 while (stack.count() > 0) 00334 { 00335 DrGroup *grp = stack.pop(); 00336 QPtrListIterator<DrGroup> git(grp->groups()); 00337 for (; git.current(); ++git) 00338 stack.push(git.current()); 00339 QPtrListIterator<DrBase> oit(grp->options()); 00340 QString value; 00341 for (; oit.current(); ++oit) 00342 { 00343 value = oit.current()->valueText(); 00344 switch (oit.current()->type()) 00345 { 00346 case DrBase::Boolean: 00347 if (value == "true") 00348 t << oit.current()->name() << "='" << value << "'" << endl; 00349 break; 00350 case DrBase::List: 00351 if (value != "(empty)") 00352 t << oit.current()->name() << "='" << value << "'" << endl; 00353 break; 00354 case DrBase::String: 00355 if (!value.isEmpty()) 00356 t << oit.current()->name() << "='" << value << "'" << endl; 00357 break; 00358 default: 00359 break; 00360 } 00361 } 00362 } 00363 return true; 00364 } 00365 else 00366 { 00367 manager()->setErrorMsg(i18n("Unable to create the file %1.").arg(f.name())); 00368 return false; 00369 } 00370 } 00371 00372 bool ApsHandler::removePrinter(KMPrinter*, PrintcapEntry *entry) 00373 { 00374 QString path(sysconfDir() + "/" + entry->name); 00375 QFile::remove(path + "/smbclient.conf"); 00376 QFile::remove(path + "/netware.conf"); 00377 QFile::remove(path + "/apsfilterrc"); 00378 if (!QDir(path).rmdir(path)) 00379 { 00380 manager()->setErrorMsg(i18n("Unable to remove directory %1.").arg(path)); 00381 return false; 00382 } 00383 return true; 00384 } 00385 00386 QString ApsHandler::printOptions(KPrinter *printer) 00387 { 00388 QString optstr; 00389 QMap<QString,QString> opts = printer->options(); 00390 for (QMap<QString,QString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it) 00391 { 00392 if (it.key().startsWith("kde-") || it.key().startsWith("_kde-") || it.key().startsWith( "app-" )) 00393 continue; 00394 optstr.append((*it)).append(":"); 00395 } 00396 if (!optstr.isEmpty()) 00397 { 00398 optstr = optstr.left(optstr.length()-1); 00399 optstr.prepend("-C '").append("'"); 00400 } 00401 return optstr; 00402 }
KDE Logo
This file is part of the documentation for kdeprint Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:32:31 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003