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 <tqtextstream.h>
#include <tqregexp.h>
#include <kdebug.h>
#include <klocale.h>
#include <kprocess.h>
#include <stdlib.h>
static TQString execute(const TQString& cmd)
{
KPipeProcess proc;
TQString output;
if (proc.open(cmd))
{
TQTextStream t(&proc);
while (!t.atEnd())
output.append(t.readLine()).append("\n");
proc.close();
}
return output;
}
LpcHelper::LpcHelper(TQObject *parent, const char *name)
: TQObject(parent, name)
{
// look for the "lpc" executable. Use the PATH variable and
// add some specific dirs.
TQString 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 TQString& 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::parsetStatusLPR(TQTextStream &t)
{
TQString 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::parsetStatusLPRng(TQTextStream& t)
{
TQStringList l;
int p(-1);
TQString printer;
while (!t.atEnd())
if (t.readLine().stripWhiteSpace().startsWith("Printer"))
break;
while (!t.atEnd())
{
l = TQStringList::split(TQRegExp("\\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"))
{
TQTextStream t(&proc);
switch (LprSettings::self()->mode())
{
default:
case LprSettings::LPR:
parsetStatusLPR(t);
break;
case LprSettings::LPRng:
parsetStatusLPRng(t);
break;
}
proc.close();
}
}
bool LpcHelper::enable(KMPrinter *prt, bool state, TQString& 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, TQString& 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 TQString& result, const TQString& 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 TQString lprngAnswer(const TQString& result, const TQString& printer)
{
int p, q;
p = result.find("\n" + printer);
if (p != -1)
{
q = result.find(':', p)+2;
p = result.find('\n', q);
TQString answer = result.mid(q, p-q).stripWhiteSpace();
return answer;
}
return TQString::null;
}
int LpcHelper::parseStateChangeLPRng(const TQString& result, const TQString& printer)
{
TQString 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 TQString& printer, const TQString& op, TQString& msg)
{
if (m_exepath.isEmpty())
{
msg = i18n("The executable %1 couldn't be found in your PATH.").arg("lpc");
return false;
}
TQString 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(TQRegExp("\\n"), " "));
break;
}
return (status == 0);
}
bool LpcHelper::removeJob(KMJob *job, TQString& msg)
{
if (m_lprmpath.isEmpty())
{
msg = i18n("The executable %1 couldn't be found in your PATH.").arg("lprm");
return false;
}
TQString result = execute(m_lprmpath + " -P " + KProcess::quote(job->printer()) + " " + TQString::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, TQString& msg)
{
if (m_lprmpath.isEmpty())
{
msg = i18n("The executable %1 couldn't be found in your PATH.").arg("lpc");
return false;
}
TQString result = execute(m_exepath + (state == KMJob::Held ? " hold " : " release ") + KProcess::quote(job->printer()) + " " + TQString::number(job->id()));
TQString answer = lprngAnswer(result, job->printer());
if (answer == "no")
{
msg = i18n("Permission denied.");
return false;
}
else
return true;
}
bool LpcHelper::restart(TQString& msg)
{
TQString 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(TQFile::encodeName(m_exepath + " reread"));
::system(TQFile::encodeName(m_checkpcpath + " -f"));
return true;
}