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.
394 lines
11 KiB
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;
|
|
}
|