00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "lpchelper.h"
00021
#include "kpipeprocess.h"
00022
#include "kmjob.h"
00023
#include "lprsettings.h"
00024
00025
#include <kstandarddirs.h>
00026
#include <qtextstream.h>
00027
#include <qregexp.h>
00028
#include <kdebug.h>
00029
#include <klocale.h>
00030
#include <kprocess.h>
00031
#include <stdlib.h>
00032
00033
static QString execute(
const QString& cmd)
00034 {
00035 KPipeProcess proc;
00036
QString output;
00037
if (proc.open(cmd))
00038 {
00039
QTextStream t(&proc);
00040
while (!t.
atEnd())
00041 output.
append(t.
readLine()).append(
"\n");
00042 proc.close();
00043 }
00044
return output;
00045 }
00046
00047 LpcHelper::LpcHelper(
QObject *parent,
const char *name)
00048 :
QObject(parent, name)
00049 {
00050
00051
00052
QString PATH = getenv(
"PATH");
00053 PATH.
append(
":/usr/sbin:/usr/local/sbin:/sbin:/opt/sbin:/opt/local/sbin");
00054 m_exepath = KStandardDirs::findExe(
"lpc", PATH);
00055 m_checkpcpath = KStandardDirs::findExe(
"checkpc", PATH);
00056 m_lprmpath = KStandardDirs::findExe(
"lprm");
00057 }
00058
00059 LpcHelper::~LpcHelper()
00060 {
00061 }
00062
00063 KMPrinter::PrinterState LpcHelper::state(
const QString& prname)
const
00064
{
00065
if (m_state.contains(prname))
00066
return m_state[prname];
00067
return KMPrinter::Unknown;
00068 }
00069
00070 KMPrinter::PrinterState LpcHelper::state(KMPrinter *prt)
const
00071
{
00072
return state(prt->printerName());
00073 }
00074
00075
void LpcHelper::parseStatusLPR(
QTextStream &t)
00076 {
00077
QString printer, line;
00078
int p(-1);
00079
00080
while (!t.
atEnd())
00081 {
00082 line = t.
readLine();
00083
if (line.
isEmpty())
00084
continue;
00085
else if (!line[0].isSpace() && (p = line.
find(
':')) != -1)
00086 {
00087 printer = line.
left(p);
00088 m_state[printer] = KMPrinter::Idle;
00089 }
00090
else if (line.
find(
"printing is disabled") != -1)
00091 {
00092
if (!printer.
isEmpty())
00093 m_state[printer] = KMPrinter::PrinterState((KMPrinter::Stopped) | (m_state[printer] & ~KMPrinter::StateMask));
00094 }
00095
else if (line.
find(
"queuing is disabled") != -1)
00096 {
00097
if (!printer.
isEmpty())
00098 m_state[printer] = KMPrinter::PrinterState((KMPrinter::Rejecting) | (m_state[printer] & KMPrinter::StateMask));
00099 }
00100
else if (line.
find(
"entries") != -1)
00101 {
00102
if (!printer.
isEmpty() &&
00103 (m_state[printer] & KMPrinter::StateMask) != KMPrinter::Stopped &&
00104 line.
find(
"no entries") == -1)
00105 m_state[printer] = KMPrinter::PrinterState((m_state[printer] & ~KMPrinter::StateMask) | KMPrinter::Processing);
00106 }
00107 }
00108 }
00109
00110
void LpcHelper::parseStatusLPRng(
QTextStream& t)
00111 {
00112
QStringList l;
00113
int p(-1);
00114
QString printer;
00115
00116
while (!t.
atEnd())
00117
if (t.
readLine().stripWhiteSpace().startsWith(
"Printer"))
00118
break;
00119
while (!t.
atEnd())
00120 {
00121 l =
QStringList::split(
QRegExp(
"\\s"), t.
readLine(),
false);
00122
if (l.count() < 4)
00123
continue;
00124 p = l[0].find(
'@');
00125
if (p == 0)
00126 printer = l[0];
00127
else
00128 printer = l[0].
left(p);
00129
int st(0);
00130
if (l[1] ==
"disabled")
00131 st = KMPrinter::Stopped;
00132
else if (l[3] !=
"0")
00133 st = KMPrinter::Processing;
00134
else
00135 st = KMPrinter::Idle;
00136
if (l[2] ==
"disabled")
00137 st |= KMPrinter::Rejecting;
00138 m_state[printer] = KMPrinter::PrinterState(st);
00139 }
00140 }
00141
00142
void LpcHelper::updateStates()
00143 {
00144 KPipeProcess proc;
00145
00146 m_state.clear();
00147
if (!m_exepath.isEmpty() && proc.open(m_exepath +
" status all"))
00148 {
00149
QTextStream t(&proc);
00150
00151
switch (LprSettings::self()->mode())
00152 {
00153
default:
00154
case LprSettings::LPR:
00155 parseStatusLPR(t);
00156
break;
00157
case LprSettings::LPRng:
00158 parseStatusLPRng(t);
00159
break;
00160 }
00161 proc.close();
00162 }
00163
00164 }
00165
00166
bool LpcHelper::enable(KMPrinter *prt,
bool state,
QString& msg)
00167 {
00168
int st = m_state[prt->printerName()] & KMPrinter::StateMask;
00169
if (changeState(prt->printerName(), (state ?
"enable" :
"disable"), msg))
00170 {
00171 m_state[prt->printerName()] = KMPrinter::PrinterState((state ? KMPrinter::Rejecting : 0) | st);
00172
return true;
00173 }
00174
return false;
00175 }
00176
00177
bool LpcHelper::start(KMPrinter *prt,
bool state,
QString& msg)
00178 {
00179
int rej = m_state[prt->printerName()] & ~KMPrinter::StateMask;
00180
if (changeState(prt->printerName(), (state ?
"start" :
"stop"), msg))
00181 {
00182 m_state[prt->printerName()] = KMPrinter::PrinterState((state ? KMPrinter::Idle : KMPrinter::Stopped) | rej);
00183
return true;
00184 }
00185
return false;
00186 }
00187
00188
00189
00190
00191
00192
00193
int LpcHelper::parseStateChangeLPR(
const QString& result,
const QString& printer)
00194 {
00195
if (result.
startsWith(printer +
":"))
00196
return 0;
00197
else if (result.
startsWith(
"?Privileged"))
00198
return -1;
00199
else if (result.
startsWith(
"unknown"))
00200
return -2;
00201
else
00202
return 1;
00203 }
00204
00205
static QString lprngAnswer(
const QString& result,
const QString& printer)
00206 {
00207
int p, q;
00208
00209 p = result.
find(
"\n" + printer);
00210
if (p != -1)
00211 {
00212 q = result.
find(
':', p)+2;
00213 p = result.
find(
'\n', q);
00214
QString answer = result.
mid(q, p-q).stripWhiteSpace();
00215
return answer;
00216 }
00217
return QString::null;
00218 }
00219
00220
int LpcHelper::parseStateChangeLPRng(
const QString& result,
const QString& printer)
00221 {
00222
QString answer = lprngAnswer(result, printer);
00223
if (answer ==
"no")
00224
return -1;
00225
else if (answer ==
"disabled" || answer ==
"enabled" || answer ==
"started" || answer ==
"stopped")
00226
return 0;
00227
else
00228
return 1;
00229 }
00230
00231
bool LpcHelper::changeState(
const QString& printer,
const QString& op,
QString& msg)
00232 {
00233
if (m_exepath.isEmpty())
00234 {
00235 msg = i18n(
"The executable %1 couldn't be found in your PATH.").
arg(
"lpc");
00236
return false;
00237 }
00238
QString result = execute(m_exepath +
" " + op +
" " + KProcess::quote(printer));
00239
int status;
00240
00241
switch (LprSettings::self()->mode())
00242 {
00243
default:
00244
case LprSettings::LPR:
00245 status = parseStateChangeLPR(result, printer);
00246
break;
00247
case LprSettings::LPRng:
00248 status = parseStateChangeLPRng(result, printer);
00249
break;
00250 }
00251
switch (status)
00252 {
00253
case 0:
00254
break;
00255
case -1:
00256 msg = i18n(
"Permission denied.");
00257
break;
00258
case -2:
00259 msg = i18n(
"Printer %1 does not exist.").
arg(printer);
00260
break;
00261
default:
00262
case 1:
00263 msg = i18n(
"Unknown error: %1").
arg(result.
replace(
QRegExp(
"\\n"),
" "));
00264
break;
00265 }
00266
return (status == 0);
00267 }
00268
00269
bool LpcHelper::removeJob(KMJob *job,
QString& msg)
00270 {
00271
if (m_lprmpath.isEmpty())
00272 {
00273 msg = i18n(
"The executable %1 couldn't be found in your PATH.").
arg(
"lprm");
00274
return false;
00275 }
00276
QString result = execute(m_lprmpath +
" -P " + KProcess::quote(job->printer()) +
" " +
QString::number(job->id()));
00277
if (result.
find(
"dequeued") != -1)
00278
return true;
00279
else if (result.
find(
"Permission denied") != -1 || result.
find(
"no permissions") != -1)
00280 msg = i18n(
"Permission denied.");
00281
else
00282 msg = i18n(
"Execution of lprm failed: %1").
arg(result);
00283
return false;
00284 }
00285
00286
00287
bool LpcHelper::changeJobState(KMJob *job,
int state,
QString& msg)
00288 {
00289
if (m_lprmpath.isEmpty())
00290 {
00291 msg = i18n(
"The executable %1 couldn't be found in your PATH.").
arg(
"lpc");
00292
return false;
00293 }
00294
QString result = execute(m_exepath + (state == KMJob::Held ?
" hold " :
" release ") + KProcess::quote(job->printer()) +
" " +
QString::number(job->id()));
00295
QString answer = lprngAnswer(result, job->printer());
00296
if (answer ==
"no")
00297 {
00298 msg = i18n(
"Permission denied.");
00299
return false;
00300 }
00301
else
00302
return true;
00303 }
00304
00305
bool LpcHelper::restart(
QString& msg)
00306 {
00307
QString s;
00308
if (m_exepath.isEmpty())
00309 s =
"lpc";
00310
else if (m_checkpcpath.isEmpty())
00311 s =
"checkpc";
00312
if (!s.
isEmpty())
00313 {
00314 msg = i18n(
"The executable %1 couldn't be found in your PATH.").
arg(s);
00315
return false;
00316 }
00317 ::system(
QFile::encodeName(m_exepath +
" reread"));
00318 ::system(
QFile::encodeName(m_checkpcpath +
" -f"));
00319
return true;
00320 }