kmlpdunixmanager.cpp00001
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 }
|