You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kdeprint/lpr/lpchelper.cpp

321 lines
7.9 KiB

/*
* 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;
}