| # kdeprint Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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         if (LprSettings::self()->mode() == LprSettings::LPR)
    00400             optstr.prepend("-C '").append("'");
    00401         else
    00402             optstr.prepend("-Z '").append("'");
    00403     }
    00404     return optstr;
    00405 }

This file is part of the documentation for kdeprint Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:31:00 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003