You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kdeprint/lpr/lprngtoolhandler.cpp

394 lines
11 KiB

/*
* 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 "lprngtoolhandler.h"
#include "printcapentry.h"
#include "kmprinter.h"
#include "util.h"
#include "lprsettings.h"
#include "driver.h"
#include "kmmanager.h"
#include "kprinter.h"
#include <qfile.h>
#include <qtextstream.h>
#include <klocale.h>
#include <kdebug.h>
#include <kstandarddirs.h>
LPRngToolHandler::LPRngToolHandler(KMManager *mgr)
: LprHandler("lprngtool", mgr)
{
}
bool LPRngToolHandler::validate(PrintcapEntry *entry)
{
if (entry->comment.startsWith("##LPRNGTOOL##") &&
entry->comment.find("UNKNOWN") == -1)
return true;
return false;
}
bool LPRngToolHandler::completePrinter(KMPrinter *prt, PrintcapEntry *entry, bool shortmode)
{
QString str, lp;
// look for type in comment
QStringList l = QStringList::split(' ', entry->comment, false);
lp = entry->field("lp");
if (l.count() < 1)
return false;
if (l[1] == "DEVICE" || l[1] == "SOCKET" || l[1] == "QUEUE")
LprHandler::completePrinter(prt, entry, shortmode);
else if (l[1] == "SMB")
{
QMap<QString,QString> opts = parseXferOptions(entry->field("xfer_options"));
QString user, pass;
loadAuthFile(LprSettings::self()->baseSpoolDir() + "/" + entry->name + "/" + opts["authfile"], user, pass);
QString uri = buildSmbURI(
opts[ "workgroup" ],
opts[ "host" ],
opts[ "printer" ],
user,
pass );
prt->setDevice( uri );
prt->setLocation(i18n("Network printer (%1)").arg("smb"));
}
// look for comment
if (!(str=entry->field("cm")).isEmpty())
prt->setDescription(str);
// driver
//if (!shortmode)
//{
if (!(str=entry->field("ifhp")).isEmpty())
{
QString model;
int p = str.find("model");
if (p != -1)
{
p = str.find('=', p);
if (p != -1)
{
p++;
int q = str.find(',', p);
if (q == -1)
model = str.mid(p);
else
model = str.mid(p, q-p);
}
}
prt->setDriverInfo(i18n("IFHP Driver (%1)").arg((model.isEmpty() ? i18n("unknown") : model)));
prt->setOption("driverID", model);
}
//}
return true;
}
QMap<QString,QString> LPRngToolHandler::parseXferOptions(const QString& str)
{
uint p(0), q;
QMap<QString,QString> opts;
QString key, val;
while (p < str.length())
{
key = val = QString::null;
// skip spaces
while (p < str.length() && str[p].isSpace())
p++;
q = p;
while (q < str.length() && str[q] != '=')
q++;
key = str.mid(p, q-p);
p = q+2;
while (p < str.length() && str[p] != '"')
p++;
val = str.mid(q+2, p-q-2);
if (!key.isEmpty())
opts[key] = val;
p++;
}
return opts;
}
void LPRngToolHandler::loadAuthFile(const QString& filename, QString& user, QString& pass)
{
QFile f(filename);
if (f.open(IO_ReadOnly))
{
QTextStream t(&f);
QString line;
while (!t.atEnd())
{
line = t.readLine().stripWhiteSpace();
if (line.isEmpty())
continue;
int p = line.find('=');
if (p != -1)
{
QString key = line.left(p);
if (key == "username")
user = line.mid(p+1);
else if (key == "password")
pass = line.mid(p+1);
}
}
}
}
DrMain* LPRngToolHandler::loadDriver(KMPrinter *prt, PrintcapEntry *entry, bool config)
{
if (entry->field("lprngtooloptions").isEmpty())
{
manager()->setErrorMsg(i18n("No driver defined for that printer. It might be a raw printer."));
return NULL;
}
DrMain* driver = loadToolDriver(locate("data", "kdeprint/lprngtooldriver1"));
if (driver)
{
QString model = prt->option("driverID");
driver->set("text", i18n("LPRngTool Common Driver (%1)").arg((model.isEmpty() ? i18n("unknown") : model)));
if (!model.isEmpty())
driver->set("driverID", model);
QMap<QString,QString> opts = parseZOptions(entry->field("prefix_z"));
opts["lpr"] = entry->field("lpr");
driver->setOptions(opts);
// if not configuring, don't show the "lpr" options
if (!config)
driver->removeOptionGlobally("lpr");
}
return driver;
}
DrMain* LPRngToolHandler::loadDbDriver(const QString& s)
{
int p = s.find('/');
DrMain* driver = loadToolDriver(locate("data", "kdeprint/lprngtooldriver1"));
if (driver)
driver->set("driverID", s.mid(p+1));
return driver;
}
QValueList< QPair<QString,QStringList> > LPRngToolHandler::loadChoiceDict(const QString& filename)
{
QFile f(filename);
QValueList< QPair<QString,QStringList> > dict;
if (f.open(IO_ReadOnly))
{
QTextStream t(&f);
QString line, key;
QStringList l;
while (!t.atEnd())
{
line = t.readLine().stripWhiteSpace();
if (line.startsWith("OPTION"))
{
if (l.count() > 0 && !key.isEmpty())
dict << QPair<QString,QStringList>(key, l);
l.clear();
key = QString::null;
if (line.contains('|') == 2 || line.right(7) == "BOOLEAN")
{
int p = line.find('|', 7);
key = line.mid(7, p-7);
}
}
else if (line.startsWith("CHOICE"))
{
int p = line.find('|', 7);
l << line.mid(7, p-7);
}
}
}
return dict;
}
QMap<QString,QString> LPRngToolHandler::parseZOptions(const QString& optstr)
{
QMap<QString,QString> opts;
QStringList l = QStringList::split(',', optstr, false);
if (l.count() == 0)
return opts;
if (m_dict.count() == 0)
m_dict = loadChoiceDict(locate("data", "kdeprint/lprngtooldriver1"));
QString unknown;
for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
{
bool found(false);
for (QValueList< QPair<QString,QStringList> >::ConstIterator p=m_dict.begin(); p!=m_dict.end() && !found; ++p)
{
if ((*p).second.find(*it) != (*p).second.end())
{
opts[(*p).first] = (*it);
found = true;
}
}
if (!found)
{
unknown.append(*it).append(',');
}
}
if (!unknown.isEmpty())
{
unknown.truncate(unknown.length()-1);
opts["filter"] = unknown;
}
return opts;
}
QString LPRngToolHandler::filterDir()
{
return driverDirectory();
}
QString LPRngToolHandler::driverDirInternal()
{
return locateDir("filters", "/usr/lib:/usr/local/lib:/opt/lib:/usr/libexec:/usr/local/libexec:/opt/libexec");
}
PrintcapEntry* LPRngToolHandler::createEntry(KMPrinter *prt)
{
QString prot = prt->deviceProtocol();
if (prot != "parallel" && prot != "lpd" && prot != "smb" && prot != "socket")
{
manager()->setErrorMsg(i18n("Unsupported backend: %1.").arg(prot));
return NULL;
}
PrintcapEntry *entry = new PrintcapEntry;
entry->addField("cm", Field::String, prt->description());
QString lp, comment("##LPRNGTOOL## ");
if (prot == "parallel")
{
comment.append("DEVICE ");
lp = prt->device().mid( 9 );
entry->addField("rw@", Field::Boolean);
}
else if (prot == "socket")
{
comment.append("SOCKET ");
KURL url( prt->device() );
lp = url.host();
if (url.port() == 0)
lp.append("%9100");
else
lp.append("%").append(QString::number(url.port()));
}
else if (prot == "lpd")
{
comment.append("QUEUE ");
KURL url( prt->device() );
lp = url.path().mid(1) + "@" + url.host();
}
else if (prot == "smb")
{
comment.append("SMB ");
lp = "| " + filterDir() + "/smbprint";
QString work, server, printer, user, passwd;
if ( splitSmbURI( prt->device(), work, server, printer, user, passwd ) )
{
entry->addField("xfer_options", Field::String, QString::fromLatin1("authfile=\"auth\" crlf=\"0\" hostip=\"\" host=\"%1\" printer=\"%2\" remote_mode=\"SMB\" share=\"//%3/%4\" workgroup=\"%5\"").arg(server).arg(printer).arg(server).arg(printer).arg(work));
QFile authfile(LprSettings::self()->baseSpoolDir() + "/" + prt->printerName() + "/auth");
if (authfile.open(IO_WriteOnly))
{
QTextStream t(&authfile);
t << "username=" << user << endl;
t << "password=" << passwd << endl;
authfile.close();
}
}
else
{
manager()->setErrorMsg( i18n( "Invalid printer backend specification: %1" ).arg( prt->device() ) );
delete entry;
return NULL;
}
}
if (prt->driver())
{
DrMain *driver = prt->driver();
comment.append("filtertype=IFHP ifhp_options=status@,sync@,pagecount@,waitend@ printerdb_entry=");
comment.append(driver->get("driverID"));
entry->addField("ifhp", Field::String, QString::fromLatin1("model=%1,status@,sync@,pagecount@,waitend@").arg(driver->get("driverID")));
entry->addField("lprngtooloptions", Field::String, QString::fromLatin1("FILTERTYPE=\"IFHP\" IFHP_OPTIONS=\"status@,sync@,pagecount@,waitend@\" PRINTERDB_ENTRY=\"%1\"").arg(driver->get("driverID")));
QMap<QString,QString> opts;
QString optstr;
driver->getOptions(opts, false);
for (QMap<QString,QString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it)
if (it.key() != "lpr")
optstr.append(*it).append(",");
if (!optstr.isEmpty())
{
optstr.truncate(optstr.length()-1);
entry->addField("prefix_z", Field::String, optstr);
}
if (!opts["lpr"].isEmpty())
entry->addField("lpr", Field::String, opts["lpr"]);
}
entry->addField("lp", Field::String, lp);
entry->comment = comment;
return entry;
}
bool LPRngToolHandler::savePrinterDriver(KMPrinter*, PrintcapEntry *entry, DrMain *driver, bool *mustSave)
{
// save options in the "prefix_z" field and tell the manager to save the printcap file
QMap<QString,QString> opts;
QString optstr;
driver->getOptions(opts, false);
for (QMap<QString,QString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it)
if (it.key() != "lpr")
optstr.append(*it).append(",");
if (!optstr.isEmpty())
optstr.truncate(optstr.length()-1);
// save options in any case, otherwise nothing will happen whn
// options are reset to their default value
entry->addField("prefix_z", Field::String, optstr);
entry->addField("lpr", Field::String, opts["lpr"]);
if (mustSave)
*mustSave = true;
return true;
}
QString LPRngToolHandler::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() == "lpr" || it.key().startsWith( "app-" ))
continue;
optstr.append(*it).append(",");
}
if (!optstr.isEmpty())
{
optstr.truncate(optstr.length()-1);
optstr.prepend("-Z '").append("'");
}
return optstr;
}