lpchelper.cpp00001
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 }
|