00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include <config.h>
00021
00022
#include "kmcupsmanager.h"
00023
#include "kmprinter.h"
00024
#include "ipprequest.h"
00025
#include "cupsinfos.h"
00026
#include "driver.h"
00027
#include "kmfactory.h"
00028
#include "kmdbentry.h"
00029
#include "cupsaddsmb2.h"
00030
#include "ippreportdlg.h"
00031
#include "kpipeprocess.h"
00032
#include "util.h"
00033
#include "foomatic2loader.h"
00034
#include "ppdloader.h"
00035
00036
#include <qfile.h>
00037
#include <qtextstream.h>
00038
#include <qregexp.h>
00039
#include <qtimer.h>
00040
#include <qsocket.h>
00041
#include <qdatetime.h>
00042
00043
#include <kdebug.h>
00044
#include <kapplication.h>
00045
#include <klocale.h>
00046
#include <kconfig.h>
00047
#include <kstandarddirs.h>
00048
#include <klibloader.h>
00049
#include <kmessagebox.h>
00050
#include <kaction.h>
00051
#include <kdialogbase.h>
00052
#include <kextendedsocket.h>
00053
#include <kprocess.h>
00054
#include <kfilterdev.h>
00055
#include <cups/cups.h>
00056
#include <cups/ppd.h>
00057
#include <math.h>
00058
00059
#define ppdi18n(s) i18n(QString::fromLocal8Bit(s).utf8())
00060
00061
void extractMaticData(
QString& buf,
const QString& filename);
00062
QString printerURI(KMPrinter *p,
bool useExistingURI =
false);
00063
QString downloadDriver(KMPrinter *p);
00064
00065
static int trials = 5;
00066
00067
00068
00069 KMCupsManager::KMCupsManager(
QObject *parent,
const char *name,
const QStringList & )
00070 : KMManager(parent,name)
00071 {
00072
00073
00074 CupsInfos::self();
00075 m_cupsdconf = 0;
00076 m_currentprinter = 0;
00077 m_socket = 0;
00078
00079 setHasManagement(
true);
00080 setPrinterOperationMask(KMManager::PrinterAll);
00081 setServerOperationMask(KMManager::ServerAll);
00082
00083
00084
00085
00086 setenv(
"LANG",
"en", 1);
00087 }
00088
00089 KMCupsManager::~KMCupsManager()
00090 {
00091
00092 }
00093
00094
QString KMCupsManager::driverDbCreationProgram()
00095 {
00096
return QString::fromLatin1(
"make_driver_db_cups");
00097 }
00098
00099
QString KMCupsManager::driverDirectory()
00100 {
00101
QString d = cupsInstallDir();
00102
if (d.isEmpty())
00103 d =
"/usr";
00104 d.append(
"/share/cups/model");
00105
00106 d.append(
":/usr/share/foomatic/db/source");
00107
return d;
00108 }
00109
00110
QString KMCupsManager::cupsInstallDir()
00111 {
00112 KConfig *conf= KMFactory::self()->printConfig();
00113 conf->setGroup(
"CUPS");
00114
QString dir = conf->readPathEntry(
"InstallDir");
00115
return dir;
00116 }
00117
00118
void KMCupsManager::reportIppError(IppRequest *req)
00119 {
00120 setErrorMsg(req->statusMessage());
00121 }
00122
00123
bool KMCupsManager::createPrinter(KMPrinter *p)
00124 {
00125
bool isclass = p->isClass(
false), result(
false);
00126 IppRequest req;
00127
QString uri;
00128
00129 uri = printerURI(p,
false);
00130 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00131
00132 p->setUri(KURL(uri));
00133
00134
if (isclass)
00135 {
00136 req.setOperation(CUPS_ADD_CLASS);
00137
QStringList members = p->members(), uris;
00138
QString s = QString::fromLocal8Bit(
"ipp://%1:%2/printers/").arg(CupsInfos::self()->host()).arg(CupsInfos::self()->port());
00139
for (QStringList::ConstIterator it=members.begin(); it!=members.end(); ++it)
00140 uris.append(s+(*it));
00141 req.addURI(IPP_TAG_PRINTER,
"member-uris",uris);
00142 }
00143
else
00144 {
00145 req.setOperation(CUPS_ADD_PRINTER);
00146
00147
00148 KMPrinter *otherP = findPrinter(p->printerName());
00149
if (!otherP || otherP->device() != p->device())
00150 {
00156 req.addURI(IPP_TAG_PRINTER,
"device-uri",p->device());
00157 }
00158
if (!p->option(
"kde-banners").isEmpty())
00159 {
00160
QStringList bans = QStringList::split(
',',p->option(
"kde-banners"),
false);
00161
while (bans.count() < 2)
00162 bans.append(
"none");
00163 req.addName(IPP_TAG_PRINTER,
"job-sheets-default",bans);
00164 }
00165 req.addInteger(IPP_TAG_PRINTER,
"job-quota-period",p->option(
"job-quota-period").toInt());
00166 req.addInteger(IPP_TAG_PRINTER,
"job-k-limit",p->option(
"job-k-limit").toInt());
00167 req.addInteger(IPP_TAG_PRINTER,
"job-page-limit",p->option(
"job-page-limit").toInt());
00168
if (!p->option(
"requesting-user-name-denied").isEmpty())
00169 req.addName(IPP_TAG_PRINTER,
"requesting-user-name-denied",QStringList::split(
",",p->option(
"requesting-user-name-denied"),
false));
00170
else if (!p->option(
"requesting-user-name-allowed").isEmpty())
00171 req.addName(IPP_TAG_PRINTER,
"requesting-user-name-allowed",QStringList::split(
",",p->option(
"requesting-user-name-allowed"),
false));
00172
else
00173 req.addName(IPP_TAG_PRINTER,
"requesting-user-name-allowed",QString::fromLatin1(
"all"));
00174 }
00175 req.addText(IPP_TAG_PRINTER,
"printer-info",p->description());
00176 req.addText(IPP_TAG_PRINTER,
"printer-location",p->location());
00177
00178
if (req.doRequest(
"/admin/"))
00179 {
00180 result =
true;
00181
if (p->driver())
00182 result = savePrinterDriver(p,p->driver());
00183
if (result)
00184 upPrinter(p,
true);
00185 }
00186
else reportIppError(&req);
00187
00188
return result;
00189 }
00190
00191
bool KMCupsManager::removePrinter(KMPrinter *p)
00192 {
00193
bool result = setPrinterState(p,CUPS_DELETE_PRINTER);
00194
return result;
00195 }
00196
00197
bool KMCupsManager::enablePrinter(KMPrinter *p,
bool state)
00198 {
00199
return setPrinterState(p, (state ? CUPS_ACCEPT_JOBS : CUPS_REJECT_JOBS));
00200 }
00201
00202
bool KMCupsManager::startPrinter(KMPrinter *p,
bool state)
00203 {
00204
return setPrinterState(p, (state ? IPP_RESUME_PRINTER : IPP_PAUSE_PRINTER));
00205 }
00206
00207
bool KMCupsManager::setDefaultPrinter(KMPrinter *p)
00208 {
00209
return setPrinterState(p,CUPS_SET_DEFAULT);
00210 }
00211
00212
bool KMCupsManager::setPrinterState(KMPrinter *p,
int state)
00213 {
00214 IppRequest req;
00215
QString uri;
00216
00217 req.setOperation(state);
00218 uri = printerURI(p);
00219 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00220
if (req.doRequest(
"/admin/"))
00221
return true;
00222 reportIppError(&req);
00223
return false;
00224 }
00225
00226
bool KMCupsManager::completePrinter(KMPrinter *p)
00227 {
00228
if (completePrinterShort(p))
00229 {
00230
00231
QString ppdname = downloadDriver(p);
00232 ppd_file_t *ppd = (ppdname.isEmpty() ? NULL : ppdOpenFile(ppdname.local8Bit()));
00233
if (ppd)
00234 {
00235 KMDBEntry entry;
00236
00237
00238
00239 entry.manufacturer = ppd->manufacturer;
00240 entry.model = ppd->shortnickname;
00241 entry.modelname = ppd->modelname;
00242
00243 entry.validate(
false);
00244
00245 p->setManufacturer(entry.manufacturer);
00246 p->setModel(entry.model);
00247 p->setDriverInfo(QString::fromLocal8Bit(ppd->nickname));
00248 ppdClose(ppd);
00249 }
00250
if (!ppdname.isEmpty())
00251 QFile::remove(ppdname);
00252
00253
return true;
00254 }
00255
return false;
00256 }
00257
00258
bool KMCupsManager::completePrinterShort(KMPrinter *p)
00259 {
00260 IppRequest req;
00261
QStringList keys;
00262
QString uri;
00263
00264 req.setOperation(IPP_GET_PRINTER_ATTRIBUTES);
00265 uri = printerURI(p,
true);
00266 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 keys.append(
"printer-info");
00309 keys.append(
"printer-make-and-model");
00310 keys.append(
"job-sheets-default");
00311 keys.append(
"job-sheets-supported");
00312 keys.append(
"job-quota-period");
00313 keys.append(
"job-k-limit");
00314 keys.append(
"job-page-limit");
00315 keys.append(
"requesting-user-name-allowed");
00316 keys.append(
"requesting-user-name-denied");
00317
if (p->isClass(
true))
00318 {
00319 keys.append(
"member-uris");
00320 keys.append(
"member-names");
00321 }
00322
else
00323 keys.append(
"device-uri");
00324 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",keys);
00325
00326
if (req.doRequest(
"/printers/"))
00327 {
00328
QString value;
00329
if (req.text(
"printer-info",value)) p->setDescription(value);
00330
00331
00332
if (req.text(
"printer-make-and-model",value)) p->setDriverInfo(value);
00333
if (req.uri(
"device-uri",value))
00334 {
00339 p->setDevice( value );
00340 }
00341
QStringList values;
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
if (req.name(
"member-names",values))
00354 p->setMembers(values);
00355
00356 req.name(
"job-sheets-default",values);
00357
while (values.count() < 2) values.append(
"none");
00358 p->setOption(
"kde-banners",values.join(QString::fromLatin1(
",")));
00359
if (req.name(
"job-sheets-supported",values)) p->setOption(
"kde-banners-supported",values.join(QString::fromLatin1(
",")));
00360
00361
00362
int ival;
00363
if (req.integer(
"job-quota-period",ival)) p->setOption(
"job-quota-period",QString::number(ival));
00364
if (req.integer(
"job-k-limit",ival)) p->setOption(
"job-k-limit",QString::number(ival));
00365
if (req.integer(
"job-page-limit",ival)) p->setOption(
"job-page-limit",QString::number(ival));
00366
00367
00368
if (req.name(
"requesting-user-name-allowed",values) && values.count() > 0)
00369 {
00370 p->removeOption(
"requesting-user-name-denied");
00371 p->setOption(
"requesting-user-name-allowed",values.join(
","));
00372 }
00373
if (req.name(
"requesting-user-name-denied",values) && values.count() > 0)
00374 {
00375 p->removeOption(
"requesting-user-name-allowed");
00376 p->setOption(
"requesting-user-name-denied",values.join(
","));
00377 }
00378
00379
return true;
00380 }
00381
00382 reportIppError(&req);
00383
return false;
00384 }
00385
00386
bool KMCupsManager::testPrinter(KMPrinter *p)
00387 {
00388
return KMManager::testPrinter(p);
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 }
00412
00413
void KMCupsManager::listPrinters()
00414 {
00415 loadServerPrinters();
00416 }
00417
00418
void KMCupsManager::loadServerPrinters()
00419 {
00420 IppRequest req;
00421
QStringList keys;
00422
00423
00424 req.setOperation(CUPS_GET_PRINTERS);
00425 keys.append(
"printer-name");
00426 keys.append(
"printer-type");
00427 keys.append(
"printer-state");
00428
00429 keys.append(
"printer-location");
00430 keys.append(
"printer-uri-supported");
00431 keys.append(
"printer-is-accepting-jobs");
00432 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",keys);
00433
00434
if (req.doRequest(
"/printers/"))
00435 {
00436 processRequest(&req);
00437
00438
00439 req.init();
00440 req.setOperation(CUPS_GET_CLASSES);
00441 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",keys);
00442
00443
if (req.doRequest(
"/classes/"))
00444 {
00445 processRequest(&req);
00446
00447
00448 req.init();
00449 req.setOperation(CUPS_GET_DEFAULT);
00450 req.addKeyword(IPP_TAG_OPERATION,
"requested-attributes",QString::fromLatin1(
"printer-name"));
00451
if (req.doRequest(
"/printers/"))
00452 {
00453
QString s = QString::null;
00454 req.name(
"printer-name",s);
00455 setHardDefault(findPrinter(s));
00456 }
00457
00458
00459
00460
00461
00462
return;
00463 }
00464 }
00465
00466
00467 reportIppError(&req);
00468 }
00469
00470
void KMCupsManager::processRequest(IppRequest* req)
00471 {
00472 ipp_attribute_t *attr = req->first();
00473 KMPrinter *printer =
new KMPrinter();
00474
while (attr)
00475 {
00476
QString attrname(attr->name);
00477
if (attrname ==
"printer-name")
00478 {
00479
QString value = QString::fromLocal8Bit(attr->values[0].string.text);
00480 printer->setName(value);
00481 printer->setPrinterName(value);
00482 }
00483
else if (attrname ==
"printer-type")
00484 {
00485
int value = attr->values[0].integer;
00486 printer->setType(0);
00487 printer->addType(((value & CUPS_PRINTER_CLASS) || (value & CUPS_PRINTER_IMPLICIT) ? KMPrinter::Class : KMPrinter::Printer));
00488
if ((value & CUPS_PRINTER_REMOTE)) printer->addType(KMPrinter::Remote);
00489
if ((value & CUPS_PRINTER_IMPLICIT)) printer->addType(KMPrinter::Implicit);
00490
00491
00492 printer->setPrinterCap( ( value & CUPS_PRINTER_OPTIONS ) >> 2 );
00493 }
00494
else if (attrname ==
"printer-state")
00495 {
00496
switch (attr->values[0].integer)
00497 {
00498
case IPP_PRINTER_IDLE: printer->setState(KMPrinter::Idle);
break;
00499
case IPP_PRINTER_PROCESSING: printer->setState(KMPrinter::Processing);
break;
00500
case IPP_PRINTER_STOPPED: printer->setState(KMPrinter::Stopped);
break;
00501 }
00502 }
00503
else if (attrname ==
"printer-uri-supported")
00504 {
00505 printer->setUri(KURL(attr->values[0].string.text));
00506 }
00507
else if (attrname ==
"printer-location")
00508 {
00509 printer->setLocation(QString::fromLocal8Bit(attr->values[0].string.text));
00510 }
00511
else if (attrname ==
"printer-is-accepting-jobs")
00512 {
00513 printer->setAcceptJobs(attr->values[0].boolean);
00514 }
00515
if (attrname.isEmpty() || attr == req->last())
00516 {
00517 addPrinter(printer);
00518 printer =
new KMPrinter();
00519 }
00520 attr = attr->next;
00521 }
00522
delete printer;
00523 }
00524
00525 DrMain* KMCupsManager::loadPrinterDriver(KMPrinter *p,
bool)
00526 {
00527
if (!p || p->isClass(
true))
00528
return NULL;
00529
00530
QString fname = downloadDriver(p);
00531 DrMain *driver(0);
00532
if (!fname.isEmpty())
00533 {
00534 driver = loadDriverFile(fname);
00535
if (driver)
00536 driver->set(
"temporary",fname);
00537 }
00538
00539
return driver;
00540 }
00541
00542 DrMain* KMCupsManager::loadFileDriver(
const QString& filename)
00543 {
00544
if (filename.startsWith(
"ppd:"))
00545
return loadDriverFile(filename.mid(4));
00546
else if (filename.startsWith(
"foomatic/"))
00547
return loadMaticDriver(filename);
00548
else
00549
return loadDriverFile(filename);
00550 }
00551
00552 DrMain* KMCupsManager::loadMaticDriver(
const QString& drname)
00553 {
00554
QStringList comps = QStringList::split(
'/', drname,
false);
00555
QString tmpFile = locateLocal(
"tmp",
"foomatic_" + kapp->randomString(8));
00556
QString PATH = getenv(
"PATH") + QString::fromLatin1(
":/usr/sbin:/usr/local/sbin:/opt/sbin:/opt/local/sbin");
00557
QString exe = KStandardDirs::findExe(
"foomatic-datafile", PATH);
00558
if (exe.isEmpty())
00559 {
00560 setErrorMsg(i18n(
"Unable to find the executable foomatic-datafile "
00561
"in your PATH. Check that Foomatic is correctly installed."));
00562
return NULL;
00563 }
00564
00565 KPipeProcess in;
00566
QFile out(tmpFile);
00567
QString cmd = KProcess::quote(exe);
00568 cmd +=
" -t cups -d ";
00569 cmd += KProcess::quote(comps[2]);
00570 cmd +=
" -p ";
00571 cmd += KProcess::quote(comps[1]);
00572
if (in.open(cmd) && out.open(IO_WriteOnly))
00573 {
00574
QTextStream tin(&in), tout(&out);
00575
QString line;
00576
while (!tin.atEnd())
00577 {
00578 line = tin.readLine();
00579 tout << line << endl;
00580 }
00581 in.close();
00582 out.close();
00583
00584 DrMain *driver = loadDriverFile(tmpFile);
00585
if (driver)
00586 {
00587 driver->set(
"template", tmpFile);
00588 driver->set(
"temporary", tmpFile);
00589
return driver;
00590 }
00591 }
00592 setErrorMsg(i18n(
"Unable to create the Foomatic driver [%1,%2]. "
00593
"Either that driver does not exist, or you don't have "
00594
"the required permissions to perform that operation.").arg(comps[1]).arg(comps[2]));
00595 QFile::remove(tmpFile);
00596
return NULL;
00597 }
00598
00599 DrMain* KMCupsManager::loadDriverFile(
const QString& fname)
00600 {
00601
if (QFile::exists(fname))
00602 {
00603
QString msg;
00604 DrMain *driver = PPDLoader::loadDriver( fname, &msg );
00605
if ( driver )
00606 {
00607 driver->set(
"template", fname );
00608
00609 }
00610
else
00611 setErrorMsg( msg );
00612
return driver;
00613 }
00614
return NULL;
00615 }
00616
00617
void KMCupsManager::saveDriverFile(DrMain *driver,
const QString& filename)
00618 {
00619 kdDebug( 500 ) <<
"Saving PPD file with template=" << driver->get(
"template" ) << endl;
00620
QIODevice *in = KFilterDev::deviceForFile( driver->get(
"template" ) );
00621
QFile out(filename);
00622
if (in && in->open(IO_ReadOnly) && out.open(IO_WriteOnly))
00623 {
00624
QTextStream tin(in), tout(&out);
00625
QString line, keyword;
00626
bool isnumeric(
false);
00627 DrBase *opt(0);
00628
00629
while (!tin.eof())
00630 {
00631 line = tin.readLine();
00632
if (line.startsWith(
"*% COMDATA #"))
00633 {
00634
int p(-1), q(-1);
00635
if ((p=line.find(
"'name'")) != -1)
00636 {
00637 p = line.find(
'\'',p+6)+1;
00638 q = line.find(
'\'',p);
00639 keyword = line.mid(p,q-p);
00640 opt = driver->findOption(keyword);
00641
if (opt && (opt->type() == DrBase::Integer || opt->type() == DrBase::Float))
00642 isnumeric =
true;
00643
else
00644 isnumeric =
false;
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
else if ((p=line.find(
"'default'")) != -1 && !keyword.isEmpty() && opt && isnumeric)
00655 {
00656
QString prefix = line.left(p+9);
00657 tout << prefix <<
" => '" << opt->valueText() <<
'\'';
00658
if (line.find(
',',p) != -1)
00659 tout <<
',';
00660 tout << endl;
00661
continue;
00662 }
00663 tout << line << endl;
00664 }
00665
else if (line.startsWith(
"*Default"))
00666 {
00667
int p = line.find(
':',8);
00668 keyword = line.mid(8,p-8);
00669 DrBase *bopt = 0;
00670
if ( keyword ==
"PageRegion" || keyword ==
"ImageableArea" || keyword ==
"PaperDimension" )
00671 bopt = driver->findOption( QString::fromLatin1(
"PageSize" ) );
00672
else
00673 bopt = driver->findOption( keyword );
00674
if (bopt)
00675
switch (bopt->type())
00676 {
00677
case DrBase::List:
00678
case DrBase::Boolean:
00679 {
00680 DrListOption *opt = static_cast<DrListOption*>(bopt);
00681
if (opt && opt->currentChoice())
00682 tout <<
"*Default" << keyword <<
": " << opt->currentChoice()->name() << endl;
00683
else
00684 tout << line << endl;
00685 }
00686
break;
00687
case DrBase::Integer:
00688 {
00689 DrIntegerOption *opt = static_cast<DrIntegerOption*>(bopt);
00690 tout <<
"*Default" << keyword <<
": " << opt->fixedVal() << endl;
00691 }
00692
break;
00693
case DrBase::Float:
00694 {
00695 DrFloatOption *opt = static_cast<DrFloatOption*>(bopt);
00696 tout <<
"*Default" << keyword <<
": " << opt->fixedVal() << endl;
00697 }
00698
break;
00699
default:
00700 tout << line << endl;
00701
break;
00702 }
00703
else
00704 tout << line << endl;
00705 }
00706
else
00707 tout << line << endl;
00708 }
00709 }
00710
delete in;
00711 }
00712
00713
bool KMCupsManager::savePrinterDriver(KMPrinter *p, DrMain *d)
00714 {
00715
QString tmpfilename = locateLocal(
"tmp",
"print_") + kapp->randomString(8);
00716
00717
00718 saveDriverFile(d,tmpfilename);
00719
00720
00721 IppRequest req;
00722
QString uri;
00723
bool result(
false);
00724
00725 req.setOperation(CUPS_ADD_PRINTER);
00726 uri = printerURI(p,
true);
00727 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00728 result = req.doFileRequest(
"/admin/",tmpfilename);
00729
00730
00731 QFile::remove(tmpfilename);
00732
00733
if (!result)
00734 reportIppError(&req);
00735
return result;
00736 }
00737
00738
void* KMCupsManager::loadCupsdConfFunction(
const char *name)
00739 {
00740
if (!m_cupsdconf)
00741 {
00742 m_cupsdconf = KLibLoader::self()->library(
"cupsdconf");
00743
if (!m_cupsdconf)
00744 {
00745 setErrorMsg(i18n(
"Library cupsdconf not found. Check your installation."));
00746
return NULL;
00747 }
00748 }
00749
void* func = m_cupsdconf->symbol(name);
00750
if (!func)
00751 setErrorMsg(i18n(
"Symbol %1 not found in cupsdconf library.").arg(name));
00752
return func;
00753 }
00754
00755
void KMCupsManager::unloadCupsdConf()
00756 {
00757
if (m_cupsdconf)
00758 {
00759 KLibLoader::self()->unloadLibrary(
"libcupsdconf");
00760 m_cupsdconf = 0;
00761 }
00762 }
00763
00764
bool KMCupsManager::restartServer()
00765 {
00766
QString msg;
00767 bool (*f1)(
QString&) = (bool(*)(
QString&))loadCupsdConfFunction(
"restartServer");
00768
bool result(
false);
00769
if (f1)
00770 {
00771 result = f1(msg);
00772
if (!result) setErrorMsg(msg);
00773 }
00774 unloadCupsdConf();
00775
return result;
00776 }
00777
00778
bool KMCupsManager::configureServer(
QWidget *parent)
00779 {
00780
QString msg;
00781 bool (*f2)(
QWidget*,
QString&) = (bool(*)(
QWidget*,
QString&))loadCupsdConfFunction(
"configureServer");
00782
bool result(
false);
00783
if (f2)
00784 {
00785 result = f2(parent, msg);
00786
if ( !result )
00787 setErrorMsg( msg );
00788 }
00789 unloadCupsdConf();
00790
return result;
00791 }
00792
00793
QStringList KMCupsManager::detectLocalPrinters()
00794 {
00795
QStringList list;
00796 IppRequest req;
00797 req.setOperation(CUPS_GET_DEVICES);
00798
if (req.doRequest(
"/"))
00799 {
00800
QString desc, uri, printer, cl;
00801 ipp_attribute_t *attr = req.first();
00802
while (attr)
00803 {
00804
QString attrname(attr->name);
00805
if (attrname ==
"device-info") desc = attr->values[0].string.text;
00806
else if (attrname ==
"device-make-and-model") printer = attr->values[0].string.text;
00807
else if (attrname ==
"device-uri") uri = attr->values[0].string.text;
00808
else if ( attrname ==
"device-class" ) cl = attr->values[ 0 ].string.text;
00809
if (attrname.isEmpty() || attr == req.last())
00810 {
00811
if (!uri.isEmpty())
00812 {
00813
if (printer ==
"Unknown") printer = QString::null;
00814 list << cl << uri << desc << printer;
00815 }
00816 uri = desc = printer = cl = QString::null;
00817 }
00818 attr = attr->next;
00819 }
00820 }
00821
return list;
00822 }
00823
00824
void KMCupsManager::createPluginActions(KActionCollection *coll)
00825 {
00826 KAction *act =
new KAction(i18n(
"&Export Driver..."),
"kdeprint_uploadsmb", 0,
this, SLOT(exportDriver()), coll,
"plugin_export_driver");
00827 act->setGroup(
"plugin");
00828 act =
new KAction(i18n(
"&Printer IPP Report"),
"kdeprint_report", 0,
this, SLOT(printerIppReport()), coll,
"plugin_printer_ipp_report");
00829 act->setGroup(
"plugin");
00830 }
00831
00832
void KMCupsManager::validatePluginActions(KActionCollection *coll, KMPrinter *pr)
00833 {
00834
00835 m_currentprinter = pr;
00836 coll->action(
"plugin_export_driver")->setEnabled(pr && pr->isLocal() && !pr->isClass(
true) && !pr->isSpecial());
00837 coll->action(
"plugin_printer_ipp_report")->setEnabled(pr && !pr->isSpecial());
00838 }
00839
00840
void KMCupsManager::exportDriver()
00841 {
00842
if (m_currentprinter && m_currentprinter->isLocal() &&
00843 !m_currentprinter->isClass(
true) && !m_currentprinter->isSpecial())
00844 {
00845
QString path = cupsInstallDir();
00846
if (path.isEmpty())
00847 path =
"/usr/share/cups";
00848
else
00849 path +=
"/share/cups";
00850 CupsAddSmb::exportDest(m_currentprinter->printerName(), path);
00851 }
00852 }
00853
00854
void KMCupsManager::printerIppReport()
00855 {
00856
if (m_currentprinter && !m_currentprinter->isSpecial())
00857 {
00858 IppRequest req;
00859
QString uri;
00860
00861 req.setOperation(IPP_GET_PRINTER_ATTRIBUTES);
00862 uri = printerURI(m_currentprinter,
true);
00863 req.addURI(IPP_TAG_OPERATION,
"printer-uri",uri);
00864
00865
00866
00867
00868
00869
00870
00871 req.dump(2);
00872
if (req.doRequest(
"/printers/"))
00873 {
00874 ippReport(req, IPP_TAG_PRINTER, i18n(
"IPP Report for %1").arg(m_currentprinter->printerName()));
00875 }
00876
else
00877 {
00878 KMessageBox::error(0,
"<p>"+i18n(
"Unable to retrieve printer information. Error received:")+
"</p>"+req.statusMessage());
00879 }
00880 }
00881 }
00882
00883
void KMCupsManager::ippReport(IppRequest& req,
int group,
const QString& caption)
00884 {
00885 IppReportDlg::report(&req, group, caption);
00886 }
00887
00888
QString KMCupsManager::stateInformation()
00889 {
00890
return QString(
"%1: %2:%3")
00891 .arg(i18n(
"Server"))
00892 .arg(CupsInfos::self()->host())
00893 .arg(CupsInfos::self()->port());
00894 }
00895
00896
void KMCupsManager::checkUpdatePossibleInternal()
00897 {
00898 kdDebug(500) <<
"Checking for update possible" << endl;
00899
delete m_socket;
00900
00901
00902
00903
00904 m_socket =
new QSocket(
this );
00905 connect( m_socket, SIGNAL( connected() ), SLOT( slotConnectionSuccess() ) );
00906 connect( m_socket, SIGNAL( error(
int ) ), SLOT( slotConnectionFailed(
int ) ) );
00907 trials = 5;
00908 QTimer::singleShot( 1,
this, SLOT( slotAsyncConnect() ) );
00909 }
00910
00911
void KMCupsManager::slotConnectionSuccess()
00912 {
00913 kdDebug(500) <<
"Connection success, trying to send a request..." << endl;
00914 m_socket->close();
00915
00916 IppRequest req;
00917 req.setOperation( CUPS_GET_PRINTERS );
00918 req.addKeyword( IPP_TAG_OPERATION,
"requested-attributes", QString::fromLatin1(
"printer-name" ) );
00919
if ( req.doRequest(
"/printers/" ) )
00920 setUpdatePossible(
true );
00921
else
00922 {
00923 kdDebug(500) <<
"Unable to get printer list" << endl;
00924
if ( trials > 0 )
00925 {
00926 trials--;
00927 QTimer::singleShot( 1000,
this, SLOT( slotAsyncConnect() ) );
00928 }
00929
else
00930 {
00931 setErrorMsg( i18n(
"Connection to CUPS server failed. Check that the CUPS server is correctly installed and running. "
00932
"Error: %1." ).arg( i18n(
"the IPP request failed for an unknown reason" ) ) );
00933 setUpdatePossible(
false );
00934 }
00935 }
00936 }
00937
00938
void KMCupsManager::slotAsyncConnect()
00939 {
00940 kdDebug(500) <<
"Starting async connect" << endl;
00941
00942 m_socket->connectToHost( CupsInfos::self()->host(), CupsInfos::self()->port() );
00943 }
00944
00945
void KMCupsManager::slotConnectionFailed(
int errcode )
00946 {
00947 kdDebug(500) <<
"Connection failed trials=" << trials << endl;
00948
if ( trials > 0 )
00949 {
00950
00951
00952 trials--;
00953 m_socket->close();
00954 QTimer::singleShot( 1000,
this, SLOT( slotAsyncConnect() ) );
00955
return;
00956 }
00957
00958 setErrorMsg( i18n(
"Connection to CUPS server failed. Check that the CUPS server is correctly installed and running. "
00959
"Error: %1." ).arg( errcode == QSocket::ErrConnectionRefused ? i18n(
"connection refused" ) : i18n(
"host not found" ) ) );
00960 setUpdatePossible(
false );
00961 }
00962
00963
void KMCupsManager::hostPingSlot() {
00964 m_hostSuccess =
true;
00965 m_lookupDone =
true;
00966 }
00967
00968
void KMCupsManager::hostPingFailedSlot() {
00969 m_hostSuccess =
false;
00970 m_lookupDone =
true;
00971 }
00972
00973
00974
00975
void extractMaticData(
QString& buf,
const QString& filename)
00976 {
00977
QFile f(filename);
00978
if (f.exists() && f.open(IO_ReadOnly))
00979 {
00980
QTextStream t(&f);
00981
QString line;
00982
while (!t.eof())
00983 {
00984 line = t.readLine();
00985
if (line.startsWith(
"*% COMDATA #"))
00986 buf.append(line.right(line.length()-12)).append(
'\n');
00987 }
00988 }
00989 }
00990
00991
QString printerURI(KMPrinter *p,
bool use)
00992 {
00993
QString uri;
00994
if (use && !p->uri().isEmpty())
00995 uri = p->uri().prettyURL();
00996
else
00997 uri =
QString(
"ipp://%1:%2/%4/%3").arg(CupsInfos::self()->host()).arg(CupsInfos::self()->port()).arg(p->printerName()).arg((p->isClass(
false) ?
"classes" :
"printers"));
00998
return uri;
00999 }
01000
01001 QString downloadDriver(KMPrinter *p)
01002 {
01003 QString driverfile, prname = p->printerName();
01004
bool changed(
false);
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 driverfile = cupsGetPPD(prname.local8Bit());
01024
01025
01026
if (changed)
01027 {
01028 cupsSetServer(CupsInfos::self()->host().local8Bit());
01029 ippSetPort(CupsInfos::self()->port());
01030 }
01031
01032
return driverfile;
01033 }
01034
01035
#include "kmcupsmanager.moc"