From ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kdeprint/lpdunix/kmlpdunixmanager.cpp | 410 ++++++++++++++++++++++++++++++++++ 1 file changed, 410 insertions(+) create mode 100644 kdeprint/lpdunix/kmlpdunixmanager.cpp (limited to 'kdeprint/lpdunix/kmlpdunixmanager.cpp') diff --git a/kdeprint/lpdunix/kmlpdunixmanager.cpp b/kdeprint/lpdunix/kmlpdunixmanager.cpp new file mode 100644 index 000000000..f19e76f8f --- /dev/null +++ b/kdeprint/lpdunix/kmlpdunixmanager.cpp @@ -0,0 +1,410 @@ +/* + * This file is part of the KDE libraries + * Copyright (c) 2001 Michael Goffioul + * + * 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 "kmlpdunixmanager.h" +#include "kmfactory.h" +#include "kmprinter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/***************** + * Utility class * + *****************/ +class KTextBuffer +{ +public: + KTextBuffer(QIODevice *dev) : m_stream(dev) {} + bool eof() const { return (m_stream.eof() && m_linebuf.isEmpty()); } + QString readLine(); + void unreadLine(const QString& l) { m_linebuf = l; } +private: + QTextStream m_stream; + QString m_linebuf; +}; + +QString KTextBuffer::readLine() +{ + QString line; + if (!m_linebuf.isEmpty()) + { + line = m_linebuf; + m_linebuf = QString::null; + } + else + line = m_stream.readLine(); + return line; +} + +/***************************** + * Various parsing functions * + *****************************/ + +// Extract a line from a KTextBuffer: +// '#' -> comments +// '\' -> line continue +// ':' or '|' -> line continue (LPRng) +// +// New entry is detected by a line which have first character different from +// '#', '|', ':'. The line is then put back in the IODevice. +QString readLine(KTextBuffer& t) +{ + QString line, buffer; + bool lineContinue(false); + + while (!t.eof()) + { + buffer = t.readLine().stripWhiteSpace(); + if (buffer.isEmpty() || buffer[0] == '#') + continue; + if (buffer[0] == '|' || buffer[0] == ':' || lineContinue || line.isEmpty()) + { + line.append(buffer); + if (line.right(1) == "\\") + { + line.truncate(line.length()-1); + line = line.stripWhiteSpace(); + lineContinue = true; + } + else + lineContinue = false; + } + else + { + t.unreadLine(buffer); + break; + } + } + return line; +} + +// extact an entry (printcap-like) +QMap readEntry(KTextBuffer& t) +{ + QString line = readLine(t); + QMap entry; + + if (!line.isEmpty()) + { + QStringList l = QStringList::split(':',line,false); + if (l.count() > 0) + { + int p(-1); + if ((p=l[0].find('|')) != -1) + entry["printer-name"] = l[0].left(p); // only keep first name (discard aliases + else + entry["printer-name"] = l[0]; + for (uint i=1; i& entry) +{ + KMPrinter *printer = new KMPrinter(); + printer->setName(entry["printer-name"]); + printer->setPrinterName(entry["printer-name"]); + printer->setType(KMPrinter::Printer); + printer->setState(KMPrinter::Idle); + return printer; +} +KMPrinter* createPrinter(const QString& prname) +{ + QMap map; + map["printer-name"] = prname; + return createPrinter(map); +} + +// this function support LPRng piping feature, it defaults to +// /etc/printcap in any other cases (basic support) +QString getPrintcapFileName() +{ + // check if LPRng system + QString printcap("/etc/printcap"); + QFile f("/etc/lpd.conf"); + if (f.exists() && f.open(IO_ReadOnly)) + { + kdDebug() << "/etc/lpd.conf found: probably LPRng system" << endl; + QTextStream t(&f); + QString line; + while (!t.eof()) + { + line = t.readLine().stripWhiteSpace(); + if (line.startsWith("printcap_path=")) + { + kdDebug() << "printcap_path entry found: " << line << endl; + QString pcentry = line.mid(14).stripWhiteSpace(); + kdDebug() << "printcap_path value: " << pcentry << endl; + if (pcentry[0] == '|') + { // printcap through pipe + printcap = locateLocal("tmp","printcap"); + QString cmd = QString::fromLatin1("echo \"all\" | %1 > %2").arg(pcentry.mid(1)).arg(printcap); + kdDebug() << "printcap obtained through pipe" << endl << "executing: " << cmd << endl; + ::system(cmd.local8Bit()); + } + break; + } + } + } + kdDebug() << "printcap file returned: " << printcap << endl; + return printcap; +} + +// "/etc/printcap" file parsing (Linux/LPR) +void KMLpdUnixManager::parseEtcPrintcap() +{ + QFile f(getPrintcapFileName()); + if (f.exists() && f.open(IO_ReadOnly)) + { + KTextBuffer t(&f); + QMap entry; + + while (!t.eof()) + { + entry = readEntry(t); + if (entry.isEmpty() || !entry.contains("printer-name") || entry.contains("server")) + continue; + if (entry["printer-name"] == "all") + { + if (entry.contains("all")) + { + // find separator + int p = entry["all"].find(QRegExp("[^a-zA-Z0-9_\\s-]")); + if (p != -1) + { + QChar c = entry["all"][p]; + QStringList prs = QStringList::split(c,entry["all"],false); + for (QStringList::ConstIterator it=prs.begin(); it!=prs.end(); ++it) + { + KMPrinter *printer = ::createPrinter(*it); + printer->setDescription(i18n("Description unavailable")); + addPrinter(printer); + } + } + } + } + else + { + KMPrinter *printer = ::createPrinter(entry); + if (entry.contains("rm")) + printer->setDescription(i18n("Remote printer queue on %1").arg(entry["rm"])); + else + printer->setDescription(i18n("Local printer")); + addPrinter(printer); + } + } + } +} + +// helper function for NIS support in Solaris-2.6 (use "ypcat printers.conf.byname") +QString getEtcPrintersConfName() +{ + QString printersconf("/etc/printers.conf"); + if (!QFile::exists(printersconf) && !KStandardDirs::findExe( "ypcat" ).isEmpty()) + { + // standard file not found, try NIS + printersconf = locateLocal("tmp","printers.conf"); + QString cmd = QString::fromLatin1("ypcat printers.conf.byname > %1").arg(printersconf); + kdDebug() << "printers.conf obtained from NIS server: " << cmd << endl; + ::system(QFile::encodeName(cmd)); + } + return printersconf; +} + +// "/etc/printers.conf" file parsing (Solaris 2.6) +void KMLpdUnixManager::parseEtcPrintersConf() +{ + QFile f(getEtcPrintersConfName()); + if (f.exists() && f.open(IO_ReadOnly)) + { + KTextBuffer t(&f); + QMap entry; + QString default_printer; + + while (!t.eof()) + { + entry = readEntry(t); + if (entry.isEmpty() || !entry.contains("printer-name")) + continue; + QString prname = entry["printer-name"]; + if (prname == "_default") + { + if (entry.contains("use")) + default_printer = entry["use"]; + } + else if (prname != "_all") + { + KMPrinter *printer = ::createPrinter(entry); + if (entry.contains("bsdaddr")) + { + QStringList l = QStringList::split(',',entry["bsdaddr"],false); + printer->setDescription(i18n("Remote printer queue on %1").arg(l[0])); + } + else + printer->setDescription(i18n("Local printer")); + addPrinter(printer); + } + } + + if (!default_printer.isEmpty()) + setSoftDefault(findPrinter(default_printer)); + } +} + +// "/etc/lp/printers/" directory parsing (Solaris non-2.6) +void KMLpdUnixManager::parseEtcLpPrinters() +{ + QDir d("/etc/lp/printers"); + const QFileInfoList *prlist = d.entryInfoList(QDir::Dirs); + if (!prlist) + return; + + QFileInfoListIterator it(*prlist); + for (;it.current();++it) + { + if (it.current()->fileName() == "." || it.current()->fileName() == "..") + continue; + QFile f(it.current()->absFilePath() + "/configuration"); + if (f.exists() && f.open(IO_ReadOnly)) + { + KTextBuffer t(&f); + QString line, remote; + while (!t.eof()) + { + line = readLine(t); + if (line.isEmpty()) continue; + if (line.startsWith("Remote:")) + { + QStringList l = QStringList::split(':',line,false); + if (l.count() > 1) remote = l[1]; + } + } + KMPrinter *printer = new KMPrinter; + printer->setName(it.current()->fileName()); + printer->setPrinterName(it.current()->fileName()); + printer->setType(KMPrinter::Printer); + printer->setState(KMPrinter::Idle); + if (!remote.isEmpty()) + printer->setDescription(i18n("Remote printer queue on %1").arg(remote)); + else + printer->setDescription(i18n("Local printer")); + addPrinter(printer); + } + } +} + +// "/etc/lp/member/" directory parsing (HP-UX) +void KMLpdUnixManager::parseEtcLpMember() +{ + QDir d("/etc/lp/member"); + const QFileInfoList *prlist = d.entryInfoList(QDir::Files); + if (!prlist) + return; + + QFileInfoListIterator it(*prlist); + for (;it.current();++it) + { + KMPrinter *printer = new KMPrinter; + printer->setName(it.current()->fileName()); + printer->setPrinterName(it.current()->fileName()); + printer->setType(KMPrinter::Printer); + printer->setState(KMPrinter::Idle); + printer->setDescription(i18n("Local printer")); + addPrinter(printer); + } +} + +// "/usr/spool/lp/interfaces/" directory parsing (IRIX 6.x) +void KMLpdUnixManager::parseSpoolInterface() +{ + QDir d("/usr/spool/interfaces/lp"); + const QFileInfoList *prlist = d.entryInfoList(QDir::Files); + if (!prlist) + return; + + QFileInfoListIterator it(*prlist); + for (;it.current();++it) + { + QFile f(it.current()->absFilePath()); + if (f.exists() && f.open(IO_ReadOnly)) + { + KTextBuffer t(&f); + QString line, remote; + + while (!t.eof()) + { + line = t.readLine().stripWhiteSpace(); + if (line.startsWith("HOSTNAME")) + { + QStringList l = QStringList::split('=',line,false); + if (l.count() > 1) remote = l[1]; + } + } + + KMPrinter *printer = new KMPrinter; + printer->setName(it.current()->fileName()); + printer->setPrinterName(it.current()->fileName()); + printer->setType(KMPrinter::Printer); + printer->setState(KMPrinter::Idle); + if (!remote.isEmpty()) + printer->setDescription(i18n("Remote printer queue on %1").arg(remote)); + else + printer->setDescription(i18n("Local printer")); + addPrinter(printer); + } + } +} + +//********************************************************************************************************* + +KMLpdUnixManager::KMLpdUnixManager(QObject *parent, const char *name, const QStringList & /*args*/) +: KMManager(parent,name) +{ + m_loaded = false; +} + +void KMLpdUnixManager::listPrinters() +{ + // load only once, if already loaded, just keep them (remove discard flag) + if (!m_loaded) + { + parseEtcPrintcap(); + parseEtcPrintersConf(); + parseEtcLpPrinters(); + parseEtcLpMember(); + parseSpoolInterface(); + m_loaded = true; + } + else + discardAllPrinters(false); +} -- cgit v1.2.1