00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kmlpdunixmanager.h"
00021
#include "kmfactory.h"
00022
#include "kmprinter.h"
00023
00024
#include <qfile.h>
00025
#include <qdir.h>
00026
#include <qfileinfo.h>
00027
#include <qtextstream.h>
00028
#include <qregexp.h>
00029
#include <klocale.h>
00030
#include <kstandarddirs.h>
00031
#include <kdebug.h>
00032
00033
#include <stdlib.h>
00034
00035
00036
00037
00038
class KTextBuffer
00039 {
00040
public:
00041 KTextBuffer(
QIODevice *dev) : m_stream(dev) {}
00042
bool eof()
const {
return (m_stream.eof() && m_linebuf.isEmpty()); }
00043
QString readLine();
00044
void unreadLine(
const QString& l) { m_linebuf = l; }
00045
private:
00046
QTextStream m_stream;
00047
QString m_linebuf;
00048 };
00049
00050
QString KTextBuffer::readLine()
00051 {
00052
QString line;
00053
if (!m_linebuf.isEmpty())
00054 {
00055 line = m_linebuf;
00056 m_linebuf = QString::null;
00057 }
00058
else
00059 line = m_stream.readLine();
00060
return line;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
QString readLine(KTextBuffer& t)
00075 {
00076
QString line, buffer;
00077
bool lineContinue(
false);
00078
00079
while (!t.eof())
00080 {
00081 buffer = t.readLine().stripWhiteSpace();
00082
if (buffer.isEmpty() || buffer[0] ==
'#')
00083
continue;
00084
if (buffer[0] ==
'|' || buffer[0] ==
':' || lineContinue || line.isEmpty())
00085 {
00086 line.append(buffer);
00087
if (line.right(1) ==
"\\")
00088 {
00089 line.truncate(line.length()-1);
00090 line = line.stripWhiteSpace();
00091 lineContinue =
true;
00092 }
00093
else
00094 lineContinue =
false;
00095 }
00096
else
00097 {
00098 t.unreadLine(buffer);
00099
break;
00100 }
00101 }
00102
return line;
00103 }
00104
00105
00106
QMap<QString,QString> readEntry(KTextBuffer& t)
00107 {
00108
QString line = readLine(t);
00109
QMap<QString,QString> entry;
00110
00111
if (!line.isEmpty())
00112 {
00113
QStringList l = QStringList::split(
':',line,
false);
00114
if (l.count() > 0)
00115 {
00116
int p(-1);
00117
if ((p=l[0].find(
'|')) != -1)
00118 entry[
"printer-name"] = l[0].left(p);
00119
else
00120 entry[
"printer-name"] = l[0];
00121
for (uint i=1; i<l.count(); i++)
00122
if ((p=l[i].find(
'=')) != -1)
00123 entry[l[i].left(p).stripWhiteSpace()] = l[i].right(l[i].length()-p-1).stripWhiteSpace();
00124
else
00125 entry[l[i].stripWhiteSpace()] = QString::null;
00126 }
00127 }
00128
return entry;
00129 }
00130
00131
00132 KMPrinter* createPrinter(
const QMap<QString,QString>& entry)
00133 {
00134 KMPrinter *printer =
new KMPrinter();
00135 printer->setName(entry[
"printer-name"]);
00136 printer->setPrinterName(entry[
"printer-name"]);
00137 printer->setType(KMPrinter::Printer);
00138 printer->setState(KMPrinter::Idle);
00139
return printer;
00140 }
00141 KMPrinter* createPrinter(
const QString& prname)
00142 {
00143
QMap<QString,QString> map;
00144 map[
"printer-name"] = prname;
00145
return createPrinter(map);
00146 }
00147
00148
00149
00150
QString getPrintcapFileName()
00151 {
00152
00153
QString printcap(
"/etc/printcap");
00154
QFile f(
"/etc/lpd.conf");
00155
if (f.exists() && f.open(IO_ReadOnly))
00156 {
00157 kdDebug() <<
"/etc/lpd.conf found: probably LPRng system" << endl;
00158
QTextStream t(&f);
00159
QString line;
00160
while (!t.eof())
00161 {
00162 line = t.readLine().stripWhiteSpace();
00163
if (line.startsWith(
"printcap_path="))
00164 {
00165 kdDebug() <<
"printcap_path entry found: " << line << endl;
00166
QString pcentry = line.mid(14).stripWhiteSpace();
00167 kdDebug() <<
"printcap_path value: " << pcentry << endl;
00168
if (pcentry[0] ==
'|')
00169 {
00170 printcap = locateLocal(
"tmp",
"printcap");
00171
QString cmd = QString::fromLatin1(
"echo \"all\" | %1 > %2").arg(pcentry.mid(1)).arg(printcap);
00172 kdDebug() <<
"printcap obtained through pipe" << endl <<
"executing: " << cmd << endl;
00173 ::system(cmd.local8Bit());
00174 }
00175
break;
00176 }
00177 }
00178 }
00179 kdDebug() <<
"printcap file returned: " << printcap << endl;
00180
return printcap;
00181 }
00182
00183
00184
void KMLpdUnixManager::parseEtcPrintcap()
00185 {
00186
QFile f(getPrintcapFileName());
00187
if (f.exists() && f.open(IO_ReadOnly))
00188 {
00189 KTextBuffer t(&f);
00190
QMap<QString,QString> entry;
00191
00192
while (!t.eof())
00193 {
00194 entry = readEntry(t);
00195
if (entry.isEmpty() || !entry.contains(
"printer-name") || entry.contains(
"server"))
00196
continue;
00197
if (entry[
"printer-name"] ==
"all")
00198 {
00199
if (entry.contains(
"all"))
00200 {
00201
00202
int p = entry[
"all"].find(
QRegExp(
"[^a-zA-Z0-9_\\s-]"));
00203
if (p != -1)
00204 {
00205
QChar c = entry[
"all"][p];
00206
QStringList prs = QStringList::split(c,entry[
"all"],
false);
00207
for (QStringList::ConstIterator it=prs.begin(); it!=prs.end(); ++it)
00208 {
00209 KMPrinter *printer = ::createPrinter(*it);
00210 printer->setDescription(i18n(
"Description unavailable"));
00211 addPrinter(printer);
00212 }
00213 }
00214 }
00215 }
00216
else
00217 {
00218 KMPrinter *printer = ::createPrinter(entry);
00219
if (entry.contains(
"rm"))
00220 printer->setDescription(i18n(
"Remote printer queue on %1").arg(entry[
"rm"]));
00221
else
00222 printer->setDescription(i18n(
"Local printer"));
00223 addPrinter(printer);
00224 }
00225 }
00226 }
00227 }
00228
00229
00230
QString getEtcPrintersConfName()
00231 {
00232
QString printersconf(
"/etc/printers.conf");
00233
if (!QFile::exists(printersconf) && !KStandardDirs::findExe(
"ypcat" ).isEmpty())
00234 {
00235
00236 printersconf = locateLocal(
"tmp",
"printers.conf");
00237
QString cmd = QString::fromLatin1(
"ypcat printers.conf.byname > %1").arg(printersconf);
00238 kdDebug() <<
"printers.conf obtained from NIS server: " << cmd << endl;
00239 ::system(QFile::encodeName(cmd));
00240 }
00241
return printersconf;
00242 }
00243
00244
00245
void KMLpdUnixManager::parseEtcPrintersConf()
00246 {
00247
QFile f(getEtcPrintersConfName());
00248
if (f.exists() && f.open(IO_ReadOnly))
00249 {
00250 KTextBuffer t(&f);
00251
QMap<QString,QString> entry;
00252
QString default_printer;
00253
00254
while (!t.eof())
00255 {
00256 entry = readEntry(t);
00257
if (entry.isEmpty() || !entry.contains(
"printer-name"))
00258
continue;
00259
QString prname = entry[
"printer-name"];
00260
if (prname ==
"_default")
00261 {
00262
if (entry.contains(
"use"))
00263 default_printer = entry[
"use"];
00264 }
00265
else if (prname !=
"_all")
00266 {
00267 KMPrinter *printer = ::createPrinter(entry);
00268
if (entry.contains(
"bsdaddr"))
00269 {
00270
QStringList l = QStringList::split(
',',entry[
"bsdaddr"],
false);
00271 printer->setDescription(i18n(
"Remote printer queue on %1").arg(l[0]));
00272 }
00273
else
00274 printer->setDescription(i18n(
"Local printer"));
00275 addPrinter(printer);
00276 }
00277 }
00278
00279
if (!default_printer.isEmpty())
00280 setSoftDefault(findPrinter(default_printer));
00281 }
00282 }
00283
00284
00285
void KMLpdUnixManager::parseEtcLpPrinters()
00286 {
00287
QDir d(
"/etc/lp/printers");
00288
const QFileInfoList *prlist = d.entryInfoList(QDir::Dirs);
00289
if (!prlist)
00290
return;
00291
00292 QFileInfoListIterator it(*prlist);
00293
for (;it.current();++it)
00294 {
00295
if (it.current()->fileName() ==
"." || it.current()->fileName() ==
"..")
00296
continue;
00297
QFile f(it.current()->absFilePath() +
"/configuration");
00298
if (f.exists() && f.open(IO_ReadOnly))
00299 {
00300 KTextBuffer t(&f);
00301
QString line, remote;
00302
while (!t.eof())
00303 {
00304 line = readLine(t);
00305
if (line.isEmpty())
continue;
00306
if (line.startsWith(
"Remote:"))
00307 {
00308
QStringList l = QStringList::split(
':',line,
false);
00309
if (l.count() > 1) remote = l[1];
00310 }
00311 }
00312 KMPrinter *printer =
new KMPrinter;
00313 printer->setName(it.current()->fileName());
00314 printer->setPrinterName(it.current()->fileName());
00315 printer->setType(KMPrinter::Printer);
00316 printer->setState(KMPrinter::Idle);
00317
if (!remote.isEmpty())
00318 printer->setDescription(i18n(
"Remote printer queue on %1").arg(remote));
00319
else
00320 printer->setDescription(i18n(
"Local printer"));
00321 addPrinter(printer);
00322 }
00323 }
00324 }
00325
00326
00327
void KMLpdUnixManager::parseEtcLpMember()
00328 {
00329
QDir d(
"/etc/lp/member");
00330
const QFileInfoList *prlist = d.entryInfoList(QDir::Files);
00331
if (!prlist)
00332
return;
00333
00334 QFileInfoListIterator it(*prlist);
00335
for (;it.current();++it)
00336 {
00337 KMPrinter *printer =
new KMPrinter;
00338 printer->setName(it.current()->fileName());
00339 printer->setPrinterName(it.current()->fileName());
00340 printer->setType(KMPrinter::Printer);
00341 printer->setState(KMPrinter::Idle);
00342 printer->setDescription(i18n(
"Local printer"));
00343 addPrinter(printer);
00344 }
00345 }
00346
00347
00348
void KMLpdUnixManager::parseSpoolInterface()
00349 {
00350
QDir d(
"/usr/spool/interfaces/lp");
00351
const QFileInfoList *prlist = d.entryInfoList(QDir::Files);
00352
if (!prlist)
00353
return;
00354
00355 QFileInfoListIterator it(*prlist);
00356
for (;it.current();++it)
00357 {
00358
QFile f(it.current()->absFilePath());
00359
if (f.exists() && f.open(IO_ReadOnly))
00360 {
00361 KTextBuffer t(&f);
00362
QString line, remote;
00363
00364
while (!t.eof())
00365 {
00366 line = t.readLine().stripWhiteSpace();
00367
if (line.startsWith(
"HOSTNAME"))
00368 {
00369
QStringList l = QStringList::split(
'=',line,
false);
00370
if (l.count() > 1) remote = l[1];
00371 }
00372 }
00373
00374 KMPrinter *printer =
new KMPrinter;
00375 printer->setName(it.current()->fileName());
00376 printer->setPrinterName(it.current()->fileName());
00377 printer->setType(KMPrinter::Printer);
00378 printer->setState(KMPrinter::Idle);
00379
if (!remote.isEmpty())
00380 printer->setDescription(i18n(
"Remote printer queue on %1").arg(remote));
00381
else
00382 printer->setDescription(i18n(
"Local printer"));
00383 addPrinter(printer);
00384 }
00385 }
00386 }
00387
00388
00389
00390 KMLpdUnixManager::KMLpdUnixManager(
QObject *parent,
const char *name,
const QStringList & )
00391 : KMManager(parent,name)
00392 {
00393 m_loaded =
false;
00394 }
00395
00396
void KMLpdUnixManager::listPrinters()
00397 {
00398
00399
if (!m_loaded)
00400 {
00401 parseEtcPrintcap();
00402 parseEtcPrintersConf();
00403 parseEtcLpPrinters();
00404 parseEtcLpMember();
00405 parseSpoolInterface();
00406 m_loaded =
true;
00407 }
00408
else
00409 discardAllPrinters(
false);
00410 }