00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 )
00167 {
00168 QMap<QString,QString> opts = loadResources(entry);
00169 if ( !config && opts.contains( "PAPERSIZE" ) )
00170 {
00171
00172
00173 opts[ "PageSize" ] = opts[ "PAPERSIZE" ];
00174
00175
00176
00177
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
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
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 if (LprSettings::self()->mode() == LprSettings::LPR)
00400 optstr.prepend("-C '").append("'");
00401 else
00402 optstr.prepend("-Z '").append("'");
00403 }
00404 return optstr;
00405 }