00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 )
00167 {
00168
QMap<QString,QString> opts = loadResources(entry);
00169
if ( !config && opts.contains(
"PAPERSIZE" ) )
00170 {
00171
00172
00173 opts[
"PageSize" ] = opts[
"PAPERSIZE" ];
00174
00175
00176
00177
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
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
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 optstr.prepend(
"-C '").append(
"'");
00400 }
00401
return optstr;
00402 }