lpchelper.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License version 2 as published by the Free Software Foundation.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Library General Public License
00015  *  along with this library; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
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     // look for the "lpc" executable. Use the PATH variable and
00051     // add some specific dirs.
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 // status
00189 //    0 : success
00190 //   -1 : permission denied
00191 //   -2 : unknown printer
00192 //    1 : unknown error
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 // LPRng only
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys