00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "lprngtoolhandler.h"
00021
#include "printcapentry.h"
00022
#include "kmprinter.h"
00023
#include "util.h"
00024
#include "lprsettings.h"
00025
#include "driver.h"
00026
#include "kmmanager.h"
00027
#include "kprinter.h"
00028
00029
#include <qfile.h>
00030
#include <qtextstream.h>
00031
#include <klocale.h>
00032
#include <kdebug.h>
00033
#include <kstandarddirs.h>
00034
00035 LPRngToolHandler::LPRngToolHandler(KMManager *mgr)
00036 : LprHandler("lprngtool", mgr)
00037 {
00038 }
00039
00040
bool LPRngToolHandler::validate(PrintcapEntry *entry)
00041 {
00042
if (entry->comment.startsWith(
"##LPRNGTOOL##") &&
00043 entry->comment.find(
"UNKNOWN") == -1)
00044
return true;
00045
return false;
00046 }
00047
00048
bool LPRngToolHandler::completePrinter(KMPrinter *prt, PrintcapEntry *entry,
bool shortmode)
00049 {
00050
QString str, lp;
00051
00052
00053
QStringList l =
QStringList::split(
' ', entry->comment,
false);
00054 lp = entry->field(
"lp");
00055
if (l.count() < 1)
00056
return false;
00057
00058
if (l[1] ==
"DEVICE" || l[1] ==
"SOCKET" || l[1] ==
"QUEUE")
00059 LprHandler::completePrinter(prt, entry, shortmode);
00060
else if (l[1] ==
"SMB")
00061 {
00062
QMap<QString,QString> opts = parseXferOptions(entry->field(
"xfer_options"));
00063
QString user, pass;
00064 loadAuthFile(LprSettings::self()->baseSpoolDir() +
"/" + entry->name +
"/" + opts[
"authfile"], user, pass);
00065
QString uri = buildSmbURI(
00066 opts[
"workgroup" ],
00067 opts[
"host" ],
00068 opts[
"printer" ],
00069 user,
00070 pass );
00071 prt->setDevice( uri );
00072 prt->setLocation(i18n(
"Network printer (%1)").arg(
"smb"));
00073 }
00074
00075
00076
if (!(str=entry->field(
"cm")).isEmpty())
00077 prt->setDescription(str);
00078
00079
00080
00081
00082
if (!(str=entry->field(
"ifhp")).isEmpty())
00083 {
00084
QString model;
00085
int p = str.
find(
"model");
00086
if (p != -1)
00087 {
00088 p = str.
find(
'=', p);
00089
if (p != -1)
00090 {
00091 p++;
00092
int q = str.
find(
',', p);
00093
if (q == -1)
00094 model = str.
mid(p);
00095
else
00096 model = str.
mid(p, q-p);
00097 }
00098 }
00099 prt->setDriverInfo(i18n(
"IFHP Driver (%1)").arg((model.
isEmpty() ? i18n(
"unknown") : model)));
00100 prt->setOption(
"driverID", model);
00101 }
00102
00103
return true;
00104 }
00105
00106
QMap<QString,QString> LPRngToolHandler::parseXferOptions(
const QString& str)
00107 {
00108 uint p(0), q;
00109
QMap<QString,QString> opts;
00110
QString key, val;
00111
00112
while (p < str.
length())
00113 {
00114 key = val = QString::null;
00115
00116
while (p < str.
length() && str[p].isSpace())
00117 p++;
00118 q = p;
00119
while (q < str.
length() && str[q] !=
'=')
00120 q++;
00121 key = str.
mid(p, q-p);
00122 p = q+2;
00123
while (p < str.
length() && str[p] !=
'"')
00124 p++;
00125 val = str.
mid(q+2, p-q-2);
00126
if (!key.
isEmpty())
00127 opts[key] = val;
00128 p++;
00129 }
00130
return opts;
00131 }
00132
00133
void LPRngToolHandler::loadAuthFile(
const QString& filename,
QString& user,
QString& pass)
00134 {
00135
QFile f(filename);
00136
if (f.
open(IO_ReadOnly))
00137 {
00138
QTextStream t(&f);
00139
QString line;
00140
while (!t.
atEnd())
00141 {
00142 line = t.
readLine().stripWhiteSpace();
00143
if (line.
isEmpty())
00144
continue;
00145
int p = line.
find(
'=');
00146
if (p != -1)
00147 {
00148
QString key = line.
left(p);
00149
if (key ==
"username")
00150 user = line.
mid(p+1);
00151
else if (key ==
"password")
00152 pass = line.
mid(p+1);
00153 }
00154 }
00155 }
00156 }
00157
00158 DrMain* LPRngToolHandler::loadDriver(KMPrinter *prt, PrintcapEntry *entry,
bool config)
00159 {
00160
if (entry->field(
"lprngtooloptions").isEmpty())
00161 {
00162 manager()->setErrorMsg(i18n(
"No driver defined for that printer. It might be a raw printer."));
00163
return NULL;
00164 }
00165
00166 DrMain* driver = loadToolDriver(locate(
"data",
"kdeprint/lprngtooldriver1"));
00167
if (driver)
00168 {
00169
QString model = prt->option(
"driverID");
00170 driver->set(
"text", i18n(
"LPRngTool Common Driver (%1)").arg((model.
isEmpty() ? i18n(
"unknown") : model)));
00171
if (!model.
isEmpty())
00172 driver->set(
"driverID", model);
00173
QMap<QString,QString> opts = parseZOptions(entry->field(
"prefix_z"));
00174 opts[
"lpr"] = entry->field(
"lpr");
00175 driver->setOptions(opts);
00176
00177
if (!config)
00178 driver->removeOptionGlobally(
"lpr");
00179 }
00180
return driver;
00181 }
00182
00183 DrMain* LPRngToolHandler::loadDbDriver(
const QString& s)
00184 {
00185
int p = s.
find(
'/');
00186 DrMain* driver = loadToolDriver(locate(
"data",
"kdeprint/lprngtooldriver1"));
00187
if (driver)
00188 driver->set(
"driverID", s.
mid(p+1));
00189
return driver;
00190 }
00191
00192
QValueList< QPair<QString,QStringList> > LPRngToolHandler::loadChoiceDict(
const QString& filename)
00193 {
00194
QFile f(filename);
00195
QValueList< QPair<QString,QStringList> > dict;
00196
if (f.
open(IO_ReadOnly))
00197 {
00198
QTextStream t(&f);
00199
QString line, key;
00200
QStringList l;
00201
while (!t.
atEnd())
00202 {
00203 line = t.
readLine().stripWhiteSpace();
00204
if (line.
startsWith(
"OPTION"))
00205 {
00206
if (l.count() > 0 && !key.
isEmpty())
00207 dict << QPair<QString,QStringList>(key, l);
00208 l.clear();
00209 key = QString::null;
00210
if (line.
contains(
'|') == 2 || line.
right(7) ==
"BOOLEAN")
00211 {
00212
int p = line.
find(
'|', 7);
00213 key = line.
mid(7, p-7);
00214 }
00215 }
00216
else if (line.
startsWith(
"CHOICE"))
00217 {
00218
int p = line.
find(
'|', 7);
00219 l << line.
mid(7, p-7);
00220 }
00221 }
00222 }
00223
return dict;
00224 }
00225
00226
QMap<QString,QString> LPRngToolHandler::parseZOptions(
const QString& optstr)
00227 {
00228
QMap<QString,QString> opts;
00229
QStringList l =
QStringList::split(
',', optstr,
false);
00230
if (l.count() == 0)
00231
return opts;
00232
00233
if (m_dict.count() == 0)
00234 m_dict = loadChoiceDict(locate(
"data",
"kdeprint/lprngtooldriver1"));
00235
00236
QString unknown;
00237
for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it)
00238 {
00239
bool found(
false);
00240
for (
QValueList< QPair<QString,QStringList> >::ConstIterator p=m_dict.begin(); p!=m_dict.
end() && !found; ++p)
00241 {
00242
if ((*p).second.find(*it) != (*p).second.end())
00243 {
00244 opts[(*p).first] = (*it);
00245 found =
true;
00246 }
00247 }
00248
if (!found)
00249 {
00250 unknown.
append(*it).append(
',');
00251 }
00252 }
00253
if (!unknown.isEmpty())
00254 {
00255 unknown.truncate(unknown.length()-1);
00256 opts[
"filter"] = unknown;
00257 }
00258
return opts;
00259 }
00260
00261
QString LPRngToolHandler::filterDir()
00262 {
00263
return driverDirectory();
00264 }
00265
00266
QString LPRngToolHandler::driverDirInternal()
00267 {
00268
return locateDir(
"filters",
"/usr/lib:/usr/local/lib:/opt/lib:/usr/libexec:/usr/local/libexec:/opt/libexec");
00269 }
00270
00271 PrintcapEntry* LPRngToolHandler::createEntry(KMPrinter *prt)
00272 {
00273
QString prot = prt->deviceProtocol();
00274
if (prot !=
"parallel" && prot !=
"lpd" && prot !=
"smb" && prot !=
"socket")
00275 {
00276 manager()->setErrorMsg(i18n(
"Unsupported backend: %1.").arg(prot));
00277
return NULL;
00278 }
00279 PrintcapEntry *entry =
new PrintcapEntry;
00280 entry->addField(
"cm", Field::String, prt->description());
00281
QString lp, comment(
"##LPRNGTOOL## ");
00282
if (prot ==
"parallel")
00283 {
00284 comment.
append(
"DEVICE ");
00285 lp = prt->device().
mid( 9 );
00286 entry->addField(
"rw@", Field::Boolean);
00287 }
00288
else if (prot ==
"socket")
00289 {
00290 comment.
append(
"SOCKET ");
00291 KURL url( prt->device() );
00292 lp = url.host();
00293
if (url.port() == 0)
00294 lp.
append(
"%9100");
00295
else
00296 lp.
append(
"%").append(QString::number(url.port()));
00297 }
00298
else if (prot ==
"lpd")
00299 {
00300 comment.
append(
"QUEUE ");
00301 KURL url( prt->device() );
00302 lp = url.path().
mid(1) +
"@" + url.host();
00303 }
00304
else if (prot ==
"smb")
00305 {
00306 comment.
append(
"SMB ");
00307 lp =
"| " + filterDir() +
"/smbprint";
00308
QString work, server, printer, user, passwd;
00309
if ( splitSmbURI( prt->device(), work, server, printer, user, passwd ) )
00310 {
00311 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));
00312
QFile authfile(LprSettings::self()->baseSpoolDir() +
"/" + prt->printerName() +
"/auth");
00313
if (authfile.
open(IO_WriteOnly))
00314 {
00315
QTextStream t(&authfile);
00316 t <<
"username=" << user << endl;
00317 t <<
"password=" << passwd << endl;
00318 authfile.
close();
00319 }
00320 }
00321
else
00322 {
00323 manager()->setErrorMsg( i18n(
"Invalid printer backend specification: %1" ).arg( prt->device() ) );
00324
delete entry;
00325
return NULL;
00326 }
00327 }
00328
00329
if (prt->driver())
00330 {
00331 DrMain *driver = prt->driver();
00332 comment.
append(
"filtertype=IFHP ifhp_options=status@,sync@,pagecount@,waitend@ printerdb_entry=");
00333 comment.
append(driver->get(
"driverID"));
00334 entry->addField(
"ifhp", Field::String, QString::fromLatin1(
"model=%1,status@,sync@,pagecount@,waitend@").arg(driver->get(
"driverID")));
00335 entry->addField(
"lprngtooloptions", Field::String, QString::fromLatin1(
"FILTERTYPE=\"IFHP\" IFHP_OPTIONS=\"status@,sync@,pagecount@,waitend@\" PRINTERDB_ENTRY=\"%1\"").arg(driver->get(
"driverID")));
00336
QMap<QString,QString> opts;
00337
QString optstr;
00338 driver->getOptions(opts,
false);
00339
for (
QMap<QString,QString>::ConstIterator it=opts.
begin(); it!=opts.
end(); ++it)
00340
if (it.key() !=
"lpr")
00341 optstr.
append(*it).append(
",");
00342
if (!optstr.isEmpty())
00343 {
00344 optstr.truncate(optstr.length()-1);
00345 entry->addField(
"prefix_z", Field::String, optstr);
00346 }
00347
if (!opts[
"lpr"].
isEmpty())
00348 entry->addField(
"lpr", Field::String, opts[
"lpr"]);
00349 }
00350
00351 entry->addField(
"lp", Field::String, lp);
00352 entry->comment = comment;
00353
00354
return entry;
00355 }
00356
00357
bool LPRngToolHandler::savePrinterDriver(KMPrinter*, PrintcapEntry *entry, DrMain *driver,
bool *mustSave)
00358 {
00359
00360
QMap<QString,QString> opts;
00361
QString optstr;
00362 driver->getOptions(opts,
false);
00363
for (
QMap<QString,QString>::ConstIterator it=opts.
begin(); it!=opts.
end(); ++it)
00364
if (it.key() !=
"lpr")
00365 optstr.
append(*it).append(
",");
00366
if (!optstr.isEmpty())
00367 optstr.truncate(optstr.length()-1);
00368
00369
00370 entry->addField(
"prefix_z", Field::String, optstr);
00371 entry->addField(
"lpr", Field::String, opts[
"lpr"]);
00372
if (mustSave)
00373 *mustSave =
true;
00374
return true;
00375 }
00376
00377
QString LPRngToolHandler::printOptions(
KPrinter *printer)
00378 {
00379
QString optstr;
00380
QMap<QString,QString> opts = printer->
options();
00381
for (
QMap<QString,QString>::ConstIterator it=opts.
begin(); it!=opts.
end(); ++it)
00382 {
00383
if (it.key().startsWith(
"kde-") || it.key().startsWith(
"_kde-") || it.key() ==
"lpr" || it.key().startsWith(
"app-" ))
00384
continue;
00385 optstr.
append(*it).append(
",");
00386 }
00387
if (!optstr.isEmpty())
00388 {
00389 optstr.truncate(optstr.length()-1);
00390 optstr.prepend(
"-Z '").append(
"'");
00391 }
00392
return optstr;
00393 }