diff options
Diffstat (limited to 'kdeprint/lpr/apshandler.cpp')
-rw-r--r-- | kdeprint/lpr/apshandler.cpp | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/kdeprint/lpr/apshandler.cpp b/kdeprint/lpr/apshandler.cpp new file mode 100644 index 000000000..5b7bef943 --- /dev/null +++ b/kdeprint/lpr/apshandler.cpp @@ -0,0 +1,405 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + **/ + +#include "apshandler.h" +#include "driver.h" +#include "printcapentry.h" +#include "kmprinter.h" +#include "lprsettings.h" +#include "kmmanager.h" +#include "util.h" +#include "kprinter.h" + +#include <qfile.h> +#include <qdir.h> +#include <qtextstream.h> +#include <qvaluestack.h> +#include <kstandarddirs.h> +#include <klocale.h> +#include <kdebug.h> + +#include <sys/types.h> +#include <sys/stat.h> + +ApsHandler::ApsHandler(KMManager *mgr) +: LprHandler("apsfilter", mgr) +{ + m_counter = 1; +} + +bool ApsHandler::validate(PrintcapEntry *entry) +{ + return (entry->field("if").right(9) == "apsfilter"); +} + +KMPrinter* ApsHandler::createPrinter(PrintcapEntry *entry) +{ + entry->comment = QString::fromLatin1("# APS%1_BEGIN:printer%2").arg(m_counter).arg(m_counter); + entry->postcomment = QString::fromLatin1("# APS%1_END - don't delete this").arg(m_counter); + m_counter++; + return LprHandler::createPrinter(entry); +} + +bool ApsHandler::completePrinter(KMPrinter *prt, PrintcapEntry *entry, bool shortmode) +{ + if (LprHandler::completePrinter(prt, entry, shortmode)) + { + if (!shortmode) + { + QMap<QString,QString> opts = loadResources(entry); + if (opts.contains("PRINTER")) + { + prt->setDescription(i18n("APS Driver (%1)").arg(opts["PRINTER"])); + prt->setDriverInfo(prt->description()); + } + } + if (prt->device().isEmpty()) + { + QString prot; + QString smbname(sysconfDir() + "/" + prt->printerName() + "/smbclient.conf"); + QString ncpname(sysconfDir() + "/" + prt->printerName() + "/netware.conf"); + if (QFile::exists(smbname)) + { + QMap<QString,QString> opts = loadVarFile(smbname); + if (opts.count() == 0) + prt->setDevice("smb://<unknown>/<unknown>"); + else + { + prt->setDevice(buildSmbURI( + opts[ "SMB_WORKGROUP" ], + opts[ "SMB_SERVER" ], + opts[ "SMB_PRINTER" ], + opts[ "SMB_USER" ], + opts[ "SMB_PASSWD" ] ) ); + } + prot = "smb"; + } + else if (QFile::exists(ncpname)) + { + QMap<QString,QString> opts = loadVarFile(ncpname); + if (opts.count() == 0) + prt->setDevice("ncp://<unknown>/<unknown>"); + else + { + QString uri = buildSmbURI( + QString::null, + opts[ "NCP_SERVER" ], + opts[ "NCP_PRINTER" ], + opts[ "NCP_USER" ], + opts[ "NCP_PASSWD" ] ); + uri.replace( 0, 3, "ncp" ); + prt->setDevice(uri); + } + prot = "ncp"; + } + if (!prt->device().isEmpty()) + prt->setLocation(i18n("Network printer (%1)").arg(prot)); + } + return true; + } + return false; +} + +QString ApsHandler::sysconfDir() +{ + return QFile::encodeName("/etc/apsfilter"); +} + +QString ApsHandler::shareDir() +{ + return driverDirectory(); +} + +QString ApsHandler::driverDirInternal() +{ + return locateDir("apsfilter/setup", "/usr/share:/usr/local/share:/opt/share"); +} + +QMap<QString,QString> ApsHandler::loadResources(PrintcapEntry *entry) +{ + return loadVarFile(sysconfDir() + "/" + (entry ? entry->name : QString::null) + "/apsfilterrc"); +} + +QMap<QString,QString> ApsHandler::loadVarFile(const QString& filename) +{ + QMap<QString,QString> opts; + QFile f(filename); + if (f.open(IO_ReadOnly)) + { + QTextStream t(&f); + QString line; + int p(-1); + while (!t.atEnd()) + { + line = t.readLine().stripWhiteSpace(); + if (line.isEmpty() || line[0] == '#' || (p = line.find('=')) == -1) + continue; + QString variable = line.left(p).stripWhiteSpace(); + QString value = line.mid(p+1).stripWhiteSpace(); + if (!value.isEmpty() && value[0] == '\'') + value = value.mid(1, value.length()-2); + opts[variable] = value; + } + } + return opts; +} + +DrMain* ApsHandler::loadDriver(KMPrinter *prt, PrintcapEntry *entry, bool config) +{ + DrMain *driver = loadApsDriver(config); + if (driver /* && config */ ) // Load resources in all case, to get the correct page size + { + QMap<QString,QString> opts = loadResources(entry); + if ( !config && opts.contains( "PAPERSIZE" ) ) + { + // this is needed to keep applications informed + // about the current selected page size + opts[ "PageSize" ] = opts[ "PAPERSIZE" ]; + + // default page size needs to be set to the actual + // value of the printer driver, otherwise it's blocked + // to A4 + DrBase *opt = driver->findOption( "PageSize" ); + if ( opt ) + opt->set( "default", opts[ "PageSize" ] ); + } + driver->setOptions(opts); + driver->set("gsdriver", opts["PRINTER"]); + } + return driver; +} + +DrMain* ApsHandler::loadDbDriver(const QString& s) +{ + int p = s.find('/'); + DrMain *driver = loadApsDriver(true); + if (driver) + driver->set("gsdriver", s.mid(p+1)); + return driver; +} + +DrMain* ApsHandler::loadApsDriver(bool config) +{ + DrMain *driver = loadToolDriver(locate("data", (config ? "kdeprint/apsdriver1" : "kdeprint/apsdriver2"))); + if (driver) + driver->set("text", "APS Common Driver"); + return driver; +} + +void ApsHandler::reset() +{ + m_counter = 1; +} + +PrintcapEntry* ApsHandler::createEntry(KMPrinter *prt) +{ + QString prot = prt->deviceProtocol(); + if (prot != "parallel" && prot != "lpd" && prot != "smb" && prot != "ncp") + { + manager()->setErrorMsg(i18n("Unsupported backend: %1.").arg(prot)); + return NULL; + } + QString path = sysconfDir() + "/" + prt->printerName(); + if (!KStandardDirs::makeDir(path, 0755)) + { + manager()->setErrorMsg(i18n("Unable to create directory %1.").arg(path)); + return NULL; + } + if (prot == "smb" || prot == "ncp") + { + // either "smb" or "ncp" + QFile::remove(path + "/smbclient.conf"); + QFile::remove(path + "/netware.conf"); + QFile f; + if (prot == "smb") + { + f.setName(path + "/smbclient.conf"); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + QString work, server, printer, user, passwd; + if ( splitSmbURI( prt->device(), work, server, printer, user, passwd ) ) + { + if (work.isEmpty()) + { + manager()->setErrorMsg(i18n("Missing element: %1.").arg("Workgroup")); + return NULL; + } + t << "SMB_SERVER='" << server << "'" << endl; + t << "SMB_PRINTER='" << printer << "'" << endl; + t << "SMB_IP=''" << endl; + t << "SMB_WORKGROUP='" << work << "'" << endl; + t << "SMB_BUFFER=1400" << endl; + t << "SMB_FLAGS='-N'" << endl; + if (!user.isEmpty()) + { + t << "SMB_USER='" << user << "'" << endl; + t << "SMB_PASSWD='" << passwd << "'" << endl; + } + } + else + { + manager()->setErrorMsg( i18n( "Invalid printer backend specification: %1" ).arg( prt->device() ) ); + return NULL; + } + } + else + { + manager()->setErrorMsg(i18n("Unable to create the file %1.").arg(f.name())); + return NULL; + } + } + else + { + f.setName(path + "/netware.conf"); + if (f.open(IO_WriteOnly)) + { + QString work, server, printer, user, passwd; + QString uri = prt->device(); + uri.replace( 0, 3, "smb" ); + if ( splitSmbURI( uri, work, server, printer, user, passwd ) ) + { + QTextStream t(&f); + t << "NCP_SERVER='" << server << "'" << endl; + t << "NCP_PRINTER='" << printer << "'" << endl; + if (!user.isEmpty()) + { + t << "NCP_USER='" << user << "'" << endl; + t << "NCP_PASSWD='" << passwd << "'" << endl; + } + } + else + { + manager()->setErrorMsg( i18n( "Invalid printer backend specification: %1" ).arg( prt->device() ) ); + return NULL; + } + } + else + { + manager()->setErrorMsg(i18n("Unable to create the file %1.").arg(f.name())); + return NULL; + } + } + // change file permissions + ::chmod(QFile::encodeName(f.name()).data(), S_IRUSR|S_IWUSR); + } + PrintcapEntry *entry = LprHandler::createEntry(prt); + if (!entry) + { + entry = new PrintcapEntry; + entry->addField("lp", Field::String, "/dev/null"); + } + QString sd = LprSettings::self()->baseSpoolDir() + "/" + prt->printerName(); + entry->addField("af", Field::String, sd + "/acct"); + entry->addField("lf", Field::String, sd + "/log"); + entry->addField("if", Field::String, sysconfDir() + "/basedir/bin/apsfilter"); + entry->comment = QString::fromLatin1("# APS%1_BEGIN:printer%2").arg(m_counter).arg(m_counter); + entry->postcomment = QString::fromLatin1("# APS%1_END").arg(m_counter); + m_counter++; + return entry; +} + +bool ApsHandler::savePrinterDriver(KMPrinter *prt, PrintcapEntry *entry, DrMain *driver, bool*) +{ + if (driver->get("gsdriver").isEmpty()) + { + manager()->setErrorMsg(i18n("The APS driver is not defined.")); + return false; + } + QFile f(sysconfDir() + "/" + prt->printerName() + "/apsfilterrc"); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "# File generated by KDEPrint" << endl; + t << "PRINTER='" << driver->get("gsdriver") << "'" << endl; + QValueStack<DrGroup*> stack; + stack.push(driver); + while (stack.count() > 0) + { + DrGroup *grp = stack.pop(); + QPtrListIterator<DrGroup> git(grp->groups()); + for (; git.current(); ++git) + stack.push(git.current()); + QPtrListIterator<DrBase> oit(grp->options()); + QString value; + for (; oit.current(); ++oit) + { + value = oit.current()->valueText(); + switch (oit.current()->type()) + { + case DrBase::Boolean: + if (value == "true") + t << oit.current()->name() << "='" << value << "'" << endl; + break; + case DrBase::List: + if (value != "(empty)") + t << oit.current()->name() << "='" << value << "'" << endl; + break; + case DrBase::String: + if (!value.isEmpty()) + t << oit.current()->name() << "='" << value << "'" << endl; + break; + default: + break; + } + } + } + return true; + } + else + { + manager()->setErrorMsg(i18n("Unable to create the file %1.").arg(f.name())); + return false; + } +} + +bool ApsHandler::removePrinter(KMPrinter*, PrintcapEntry *entry) +{ + QString path(sysconfDir() + "/" + entry->name); + QFile::remove(path + "/smbclient.conf"); + QFile::remove(path + "/netware.conf"); + QFile::remove(path + "/apsfilterrc"); + if (!QDir(path).rmdir(path)) + { + manager()->setErrorMsg(i18n("Unable to remove directory %1.").arg(path)); + return false; + } + return true; +} + +QString ApsHandler::printOptions(KPrinter *printer) +{ + QString optstr; + QMap<QString,QString> opts = printer->options(); + for (QMap<QString,QString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it) + { + if (it.key().startsWith("kde-") || it.key().startsWith("_kde-") || it.key().startsWith( "app-" )) + continue; + optstr.append((*it)).append(":"); + } + if (!optstr.isEmpty()) + { + optstr = optstr.left(optstr.length()-1); + if (LprSettings::self()->mode() == LprSettings::LPR) + optstr.prepend("-C '").append("'"); + else + optstr.prepend("-Z '").append("'"); + } + return optstr; +} |