summaryrefslogtreecommitdiffstats
path: root/kdeprint/lpr/lpchelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdeprint/lpr/lpchelper.cpp')
-rw-r--r--kdeprint/lpr/lpchelper.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/kdeprint/lpr/lpchelper.cpp b/kdeprint/lpr/lpchelper.cpp
new file mode 100644
index 000000000..b4cd6f9e1
--- /dev/null
+++ b/kdeprint/lpr/lpchelper.cpp
@@ -0,0 +1,320 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
+ *
+ * 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 "lpchelper.h"
+#include "kpipeprocess.h"
+#include "kmjob.h"
+#include "lprsettings.h"
+
+#include <kstandarddirs.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <stdlib.h>
+
+static QString execute(const QString& cmd)
+{
+ KPipeProcess proc;
+ QString output;
+ if (proc.open(cmd))
+ {
+ QTextStream t(&proc);
+ while (!t.atEnd())
+ output.append(t.readLine()).append("\n");
+ proc.close();
+ }
+ return output;
+}
+
+LpcHelper::LpcHelper(QObject *parent, const char *name)
+: QObject(parent, name)
+{
+ // look for the "lpc" executable. Use the PATH variable and
+ // add some specific dirs.
+ QString PATH = getenv("PATH");
+ PATH.append(":/usr/sbin:/usr/local/sbin:/sbin:/opt/sbin:/opt/local/sbin");
+ m_exepath = KStandardDirs::findExe("lpc", PATH);
+ m_checkpcpath = KStandardDirs::findExe("checkpc", PATH);
+ m_lprmpath = KStandardDirs::findExe("lprm");
+}
+
+LpcHelper::~LpcHelper()
+{
+}
+
+KMPrinter::PrinterState LpcHelper::state(const QString& prname) const
+{
+ if (m_state.contains(prname))
+ return m_state[prname];
+ return KMPrinter::Unknown;
+}
+
+KMPrinter::PrinterState LpcHelper::state(KMPrinter *prt) const
+{
+ return state(prt->printerName());
+}
+
+void LpcHelper::parseStatusLPR(QTextStream &t)
+{
+ QString printer, line;
+ int p(-1);
+
+ while (!t.atEnd())
+ {
+ line = t.readLine();
+ if (line.isEmpty())
+ continue;
+ else if (!line[0].isSpace() && (p = line.find(':')) != -1)
+ {
+ printer = line.left(p);
+ m_state[printer] = KMPrinter::Idle;
+ }
+ else if (line.find("printing is disabled") != -1)
+ {
+ if (!printer.isEmpty())
+ m_state[printer] = KMPrinter::PrinterState((KMPrinter::Stopped) | (m_state[printer] & ~KMPrinter::StateMask));
+ }
+ else if (line.find("queuing is disabled") != -1)
+ {
+ if (!printer.isEmpty())
+ m_state[printer] = KMPrinter::PrinterState((KMPrinter::Rejecting) | (m_state[printer] & KMPrinter::StateMask));
+ }
+ else if (line.find("entries") != -1)
+ {
+ if (!printer.isEmpty() &&
+ (m_state[printer] & KMPrinter::StateMask) != KMPrinter::Stopped &&
+ line.find("no entries") == -1)
+ m_state[printer] = KMPrinter::PrinterState((m_state[printer] & ~KMPrinter::StateMask) | KMPrinter::Processing);
+ }
+ }
+}
+
+void LpcHelper::parseStatusLPRng(QTextStream& t)
+{
+ QStringList l;
+ int p(-1);
+ QString printer;
+
+ while (!t.atEnd())
+ if (t.readLine().stripWhiteSpace().startsWith("Printer"))
+ break;
+ while (!t.atEnd())
+ {
+ l = QStringList::split(QRegExp("\\s"), t.readLine(), false);
+ if (l.count() < 4)
+ continue;
+ p = l[0].find('@');
+ if (p == 0)
+ printer = l[0];
+ else
+ printer = l[0].left(p);
+ int st(0);
+ if (l[1] == "disabled")
+ st = KMPrinter::Stopped;
+ else if (l[3] != "0")
+ st = KMPrinter::Processing;
+ else
+ st = KMPrinter::Idle;
+ if (l[2] == "disabled")
+ st |= KMPrinter::Rejecting;
+ m_state[printer] = KMPrinter::PrinterState(st);
+ }
+}
+
+void LpcHelper::updateStates()
+{
+ KPipeProcess proc;
+
+ m_state.clear();
+ if (!m_exepath.isEmpty() && proc.open(m_exepath + " status all"))
+ {
+ QTextStream t(&proc);
+
+ switch (LprSettings::self()->mode())
+ {
+ default:
+ case LprSettings::LPR:
+ parseStatusLPR(t);
+ break;
+ case LprSettings::LPRng:
+ parseStatusLPRng(t);
+ break;
+ }
+ proc.close();
+ }
+
+}
+
+bool LpcHelper::enable(KMPrinter *prt, bool state, QString& msg)
+{
+ int st = m_state[prt->printerName()] & KMPrinter::StateMask;
+ if (changeState(prt->printerName(), (state ? "enable" : "disable"), msg))
+ {
+ m_state[prt->printerName()] = KMPrinter::PrinterState((state ? KMPrinter::Rejecting : 0) | st);
+ return true;
+ }
+ return false;
+}
+
+bool LpcHelper::start(KMPrinter *prt, bool state, QString& msg)
+{
+ int rej = m_state[prt->printerName()] & ~KMPrinter::StateMask;
+ if (changeState(prt->printerName(), (state ? "start" : "stop"), msg))
+ {
+ m_state[prt->printerName()] = KMPrinter::PrinterState((state ? KMPrinter::Idle : KMPrinter::Stopped) | rej);
+ return true;
+ }
+ return false;
+}
+
+// status
+// 0 : success
+// -1 : permission denied
+// -2 : unknown printer
+// 1 : unknown error
+int LpcHelper::parseStateChangeLPR(const QString& result, const QString& printer)
+{
+ if (result.startsWith(printer + ":"))
+ return 0;
+ else if (result.startsWith("?Privileged"))
+ return -1;
+ else if (result.startsWith("unknown"))
+ return -2;
+ else
+ return 1;
+}
+
+static QString lprngAnswer(const QString& result, const QString& printer)
+{
+ int p, q;
+
+ p = result.find("\n" + printer);
+ if (p != -1)
+ {
+ q = result.find(':', p)+2;
+ p = result.find('\n', q);
+ QString answer = result.mid(q, p-q).stripWhiteSpace();
+ return answer;
+ }
+ return QString::null;
+}
+
+int LpcHelper::parseStateChangeLPRng(const QString& result, const QString& printer)
+{
+ QString answer = lprngAnswer(result, printer);
+ if (answer == "no")
+ return -1;
+ else if (answer == "disabled" || answer == "enabled" || answer == "started" || answer == "stopped")
+ return 0;
+ else
+ return 1;
+}
+
+bool LpcHelper::changeState(const QString& printer, const QString& op, QString& msg)
+{
+ if (m_exepath.isEmpty())
+ {
+ msg = i18n("The executable %1 couldn't be found in your PATH.").arg("lpc");
+ return false;
+ }
+ QString result = execute(m_exepath + " " + op + " " + KProcess::quote(printer));
+ int status;
+
+ switch (LprSettings::self()->mode())
+ {
+ default:
+ case LprSettings::LPR:
+ status = parseStateChangeLPR(result, printer);
+ break;
+ case LprSettings::LPRng:
+ status = parseStateChangeLPRng(result, printer);
+ break;
+ }
+ switch (status)
+ {
+ case 0:
+ break;
+ case -1:
+ msg = i18n("Permission denied.");
+ break;
+ case -2:
+ msg = i18n("Printer %1 does not exist.").arg(printer);
+ break;
+ default:
+ case 1:
+ msg = i18n("Unknown error: %1").arg(result.replace(QRegExp("\\n"), " "));
+ break;
+ }
+ return (status == 0);
+}
+
+bool LpcHelper::removeJob(KMJob *job, QString& msg)
+{
+ if (m_lprmpath.isEmpty())
+ {
+ msg = i18n("The executable %1 couldn't be found in your PATH.").arg("lprm");
+ return false;
+ }
+ QString result = execute(m_lprmpath + " -P " + KProcess::quote(job->printer()) + " " + QString::number(job->id()));
+ if (result.find("dequeued") != -1)
+ return true;
+ else if (result.find("Permission denied") != -1 || result.find("no permissions") != -1)
+ msg = i18n("Permission denied.");
+ else
+ msg = i18n("Execution of lprm failed: %1").arg(result);
+ return false;
+}
+
+// LPRng only
+bool LpcHelper::changeJobState(KMJob *job, int state, QString& msg)
+{
+ if (m_lprmpath.isEmpty())
+ {
+ msg = i18n("The executable %1 couldn't be found in your PATH.").arg("lpc");
+ return false;
+ }
+ QString result = execute(m_exepath + (state == KMJob::Held ? " hold " : " release ") + KProcess::quote(job->printer()) + " " + QString::number(job->id()));
+ QString answer = lprngAnswer(result, job->printer());
+ if (answer == "no")
+ {
+ msg = i18n("Permission denied.");
+ return false;
+ }
+ else
+ return true;
+}
+
+bool LpcHelper::restart(QString& msg)
+{
+ QString s;
+ if (m_exepath.isEmpty())
+ s = "lpc";
+ else if (m_checkpcpath.isEmpty())
+ s = "checkpc";
+ if (!s.isEmpty())
+ {
+ msg = i18n("The executable %1 couldn't be found in your PATH.").arg(s);
+ return false;
+ }
+ ::system(QFile::encodeName(m_exepath + " reread"));
+ ::system(QFile::encodeName(m_checkpcpath + " -f"));
+ return true;
+}