20 #include "kmlpdmanager.h"
21 #include "kmprinter.h"
22 #include "kmdbentry.h"
24 #include "kmfactory.h"
26 #include "gschecker.h"
27 #include "kpipeprocess.h"
30 #include <tqfileinfo.h>
31 #include <tqtextstream.h>
35 #include <tdelocale.h>
36 #include <kstandarddirs.h>
37 #include <tdeconfig.h>
38 #include <tdeprocess.h>
47 TQString lpdprefix =
"";
48 TQString ptPrinterType(KMPrinter*);
52 KMLpdManager::KMLpdManager(TQObject *parent,
const char *name)
53 : KMManager(parent,name)
55 m_entries.setAutoDelete(
true);
56 m_ptentries.setAutoDelete(
true);
57 setHasManagement(getuid() == 0);
58 setPrinterOperationMask(KMManager::PrinterCreation|KMManager::PrinterConfigure|KMManager::PrinterRemoval|KMManager::PrinterEnabling);
59 m_gschecker =
new GsChecker(
this,
"GsChecker");
62 KMLpdManager::~KMLpdManager()
66 TQString KMLpdManager::driverDbCreationProgram()
68 return TQString::fromLatin1(
"make_driver_db_lpd");
71 TQString KMLpdManager::driverDirectory()
73 return TQString::fromLatin1(
"/usr/lib/rhs/rhs-printfilters");
76 bool KMLpdManager::completePrinter(KMPrinter *printer)
78 return completePrinterShort(printer);
81 bool KMLpdManager::completePrinterShort(KMPrinter *printer)
83 PrintcapEntry *entry = m_entries.find(printer->name());
86 TQString type(entry->comment(2)), driver(entry->comment(7)), lp(entry->arg(
"lp"));
87 printer->setDescription(i18n(
"Local printer queue (%1)").arg(type.isEmpty() ? i18n(
"Unknown type of local printer queue",
"Unknown") : type));
88 printer->setLocation(i18n(
"<Not available>"));
89 printer->setDriverInfo(driver.isEmpty() ? i18n(
"Unknown Driver",
"Unknown") : driver);
92 if (!entry->arg(
"rm").isEmpty())
94 url = TQString::fromLatin1(
"lpd://%1/%2").arg(entry->arg(
"rm")).arg(entry->arg(
"rp"));
95 printer->setDescription(i18n(
"Remote LPD queue %1@%2").arg(entry->arg(
"rp")).arg(entry->arg(
"rm")));
97 else if (!lp.isEmpty() && lp !=
"/dev/null")
98 url = TQString::fromLatin1(
"parallel:%1").arg(lp);
99 else if (TQFile::exists(entry->arg(
"sd")+
"/.config"))
101 TQMap<TQString,TQString> map = loadPrinttoolCfgFile(entry->arg(
"sd")+
"/.config");
104 QStringList l = TQStringList::split(
'\\',map[
"share"],
false);
105 if (map[
"workgroup"].isEmpty())
106 url = TQString::fromLatin1(
"smb://%1/%2").arg(l[0]).arg(l[1]);
108 url = TQString::fromLatin1(
"smb://%1/%2/%3").arg(map[
"workgroup"]).arg(l[0]).arg(l[1]);
109 url.setUser(map[
"user"]);
110 url.setPass(map[
"password"]);
112 else if (type ==
"DIRECT")
113 url = TQString::fromLatin1(
"socket://%1:%2").arg(map[
"printer_ip"]).arg(map[
"port"]);
114 else if (type ==
"NCP")
116 url = TQString::fromLatin1(
"ncp://%1/%2").arg(map[
"server"]).arg(map[
"queue"]);
117 url.setUser(map[
"user"]);
118 url.setPass(map[
"password"]);
121 printer->setDevice(url);
127 bool KMLpdManager::createPrinter(KMPrinter *printer)
130 PrintcapEntry *ent = findPrintcapEntry(printer->printerName());
133 ent =
new PrintcapEntry();
134 ent->m_name = printer->printerName();
138 if (!printer->driver() && printer->option(
"kde-driver") !=
"raw")
139 printer->setDriver(loadPrinterDriver(printer,
true));
141 ent = m_entries.take(ent->m_name);
145 if (printer->device().protocol() ==
"lpd")
148 ent->m_args[
"rm"] = printer->device().host();
149 ent->m_args[
"rp"] = printer->device().path().replace(
"/",TQString::fromLatin1(
""));
150 ent->m_args[
"lpd_bounce"] =
"true";
151 ent->m_comment = TQString::fromLatin1(
"##PRINTTOOL3## REMOTE");
153 ent->m_args[
"mx"] = (printer->option(
"mx").isEmpty() ?
"#0" : printer->option(
"mx"));
154 ent->m_args[
"sh"] = TQString::null;
156 if (!createSpooldir(ent))
158 setErrorMsg(i18n(
"Unable to create spool directory %1 for printer %2.").arg(ent->arg(
"sd")).arg(ent->m_name));
162 if (!printer->driver() || printer->driver()->get(
"drtype") ==
"printtool")
163 if (!createPrinttoolEntry(printer,ent))
165 setErrorMsg(i18n(
"Unable to save information for printer <b>%1</b>.").arg(printer->printerName()));
171 m_entries.insert(ent->m_name,ent);
172 if (!writePrinters())
176 if (printer->driver())
178 if (!savePrinterDriver(printer,printer->driver()))
180 m_entries.remove(ent->m_name);
187 TQCString cmd =
"chmod -R o-rwx,g+rwX ";
188 cmd += TQFile::encodeName(TDEProcess::quote(ent->arg(
"sd")));
189 cmd +=
"&& chown -R lp.lp ";
190 cmd += TQFile::encodeName(TDEProcess::quote(ent->arg(
"sd")));
191 if (system(cmd.data()) != 0)
193 setErrorMsg(i18n(
"Unable to set correct permissions on spool directory %1 for printer <b>%2</b>.").arg(ent->arg(
"sd")).arg(ent->m_name));
200 bool KMLpdManager::removePrinter(KMPrinter *printer)
202 PrintcapEntry *ent = findPrintcapEntry(printer->printerName());
205 ent = m_entries.take(printer->printerName());
206 if (!writePrinters())
208 m_entries.insert(ent->m_name,ent);
211 TQCString cmd =
"rm -rf ";
212 cmd += TQFile::encodeName(TDEProcess::quote(ent->arg(
"sd")));
221 bool KMLpdManager::enablePrinter(KMPrinter *printer,
bool state)
224 TQString cmd = programName(0);
226 cmd += state ?
"up" :
"down";
228 cmd += TDEProcess::quote(printer->printerName());
231 QTextStream t(&proc);
234 buffer.append(t.readLine());
235 if (buffer.startsWith(
"?Privilege"))
237 setErrorMsg(i18n(
"Permission denied: you must be root."));
244 setErrorMsg(i18n(
"Unable to execute command \"%1\".").arg(cmd));
249 bool KMLpdManager::enablePrinter(KMPrinter *printer)
251 return enablePrinter(printer,
true);
254 bool KMLpdManager::disablePrinter(KMPrinter *printer)
256 return enablePrinter(printer,
false);
259 void KMLpdManager::listPrinters()
262 loadPrintcapFile(TQString::fromLatin1(
"%1/etc/printcap").arg(lpdprefix));
264 TQDictIterator<PrintcapEntry> it(m_entries);
265 for (;it.current();++it)
267 KMPrinter *printer = it.current()->createPrinter();
274 TQString KMLpdManager::programName(
int f)
276 TDEConfig *conf = KMFactory::self()->printConfig();
277 conf->setGroup(
"LPD");
280 case 0:
return conf->readPathEntry(
"LpdCommand",
"/usr/sbin/lpc");
281 case 1:
return conf->readPathEntry(
"LpdQueue",
"lpq");
282 case 2:
return conf->readPathEntry(
"LpdRemove",
"lprm");
284 return TQString::null;
287 void KMLpdManager::checkStatus()
290 TQString cmd = programName(0) +
" status all";
293 QTextStream t(&proc);
295 KMPrinter *printer(0);
299 line = t.readLine().stripWhiteSpace();
302 if ((p=line.find(
':')) != -1)
303 printer = findPrinter(line.left(p));
304 else if (line.startsWith(
"printing") && printer)
305 printer->setState(line.find(
"enabled") != -1 ? KMPrinter::Idle : KMPrinter::Stopped);
306 else if (line.find(
"entries") != -1 && printer)
307 if (!line.startsWith(
"no") && printer->state() == KMPrinter::Idle)
308 printer->setState(KMPrinter::Processing);
313 bool KMLpdManager::writePrinters()
315 if (!writePrintcapFile(TQString::fromLatin1(
"%1/etc/printcap").arg(lpdprefix)))
317 setErrorMsg(i18n(
"Unable to write printcap file."));
323 void KMLpdManager::loadPrintcapFile(
const TQString& filename)
326 if (f.exists() && f.open(IO_ReadOnly))
329 TQString line, comment;
330 PrintcapEntry *entry;
333 line = getPrintcapLine(t,&comment);
336 entry =
new PrintcapEntry;
337 if (entry->readLine(line))
339 m_entries.insert(entry->m_name,entry);
340 entry->m_comment = comment;
351 bool KMLpdManager::writePrintcapFile(
const TQString& filename)
354 if (f.open(IO_WriteOnly))
357 t <<
"# File generated by TDE print (LPD plugin).\n#Don't edit by hand." << endl << endl;
358 TQDictIterator<PrintcapEntry> it(m_entries);
359 for (;it.current();++it)
360 it.current()->writeEntry(t);
366 PrinttoolEntry* KMLpdManager::findPrinttoolEntry(
const TQString& name)
368 if (m_ptentries.count() == 0)
369 loadPrinttoolDb(driverDirectory()+
"/printerdb");
370 PrinttoolEntry *ent = m_ptentries.find(name);
372 setErrorMsg(i18n(
"Couldn't find driver <b>%1</b> in printtool database.").arg(name));
376 void KMLpdManager::loadPrinttoolDb(
const TQString& filename)
379 if (f.exists() && f.open(IO_ReadOnly))
382 PrinttoolEntry *entry =
new PrinttoolEntry;
383 while (entry->readEntry(t))
385 m_ptentries.insert(entry->m_name,entry);
386 entry =
new PrinttoolEntry;
392 DrMain* KMLpdManager::loadDbDriver(KMDBEntry *entry)
394 TQString ptdbfilename = driverDirectory() +
"/printerdb";
395 if (entry->file == ptdbfilename)
397 PrinttoolEntry *ptentry = findPrinttoolEntry(entry->modelname);
400 DrMain *dr = ptentry->createDriver();
407 PrintcapEntry* KMLpdManager::findPrintcapEntry(
const TQString& name)
409 PrintcapEntry *ent = m_entries.find(name);
411 setErrorMsg(i18n(
"Couldn't find printer <b>%1</b> in printcap file.").arg(name));
415 DrMain* KMLpdManager::loadPrinterDriver(KMPrinter *printer,
bool config)
417 PrintcapEntry *entry = findPrintcapEntry(printer->name());
422 TQString sd = entry->arg(
"sd"), dr(entry->comment(7));
423 if (TQFile::exists(sd+
"/postscript.cfg") && config && !dr.isEmpty())
425 TQMap<TQString,TQString> map = loadPrinttoolCfgFile(sd+
"/postscript.cfg");
426 PrinttoolEntry *ptentry = findPrinttoolEntry(dr);
429 DrMain *dr = ptentry->createDriver();
431 map = loadPrinttoolCfgFile(sd+
"/general.cfg");
433 map = loadPrinttoolCfgFile(sd+
"/textonly.cfg");
439 if (entry->m_comment.startsWith(
"##PRINTTOOL3##"))
440 setErrorMsg(i18n(
"No driver found (raw printer)"));
442 setErrorMsg(i18n(
"Printer type not recognized."));
446 bool KMLpdManager::checkGsDriver(
const TQString& gsdriver)
448 if (gsdriver ==
"ppa" || gsdriver ==
"POSTSCRIPT" || gsdriver ==
"TEXT")
450 else if (!m_gschecker->checkGsDriver(gsdriver))
452 setErrorMsg(i18n(
"The driver device <b>%1</b> is not compiled in your GhostScript distribution. Check your installation or use another driver.").arg(gsdriver));
458 TQMap<TQString,TQString> KMLpdManager::loadPrinttoolCfgFile(
const TQString& filename)
461 TQMap<TQString,TQString> map;
462 if (f.exists() && f.open(IO_ReadOnly))
465 TQString line, name, val;
469 line = getPrintcapLine(t);
472 if (line.startsWith(
"export "))
473 line.replace(0,7,
"");
474 if ((p=line.find(
'=')) != -1)
477 val = line.right(line.length()-p-1);
478 val.replace(
"\"",
"");
480 if (!name.isEmpty() && !val.isEmpty())
488 bool KMLpdManager::savePrinttoolCfgFile(
const TQString& templatefile,
const TQString& dirname,
const TQMap<TQString,TQString>& options)
491 TQString fname = TQFileInfo(templatefile).fileName();
492 fname.replace(TQRegExp(
"\\.in$"),TQString::fromLatin1(
""));
493 QFile fin(templatefile);
494 QFile fout(dirname +
"/" + fname);
495 if (fin.exists() && fin.open(IO_ReadOnly) && fout.open(IO_WriteOnly))
497 QTextStream tin(&fin), tout(&fout);
502 line = tin.readLine().stripWhiteSpace();
503 if (line.isEmpty() || line[0] ==
'#')
505 tout << line << endl;
508 if (line.startsWith(
"export "))
511 line.replace(0,7,TQString::fromLatin1(
""));
513 if ((p=line.find(
'=')) != -1)
516 tout << name <<
'=' << options[name] << endl;
524 bool KMLpdManager::savePrinterDriver(KMPrinter *printer, DrMain *driver)
529 PrintcapEntry *ent = findPrintcapEntry(printer->printerName());
532 spooldir = ent->arg(
"sd");
534 if (driver->get(
"drtype") ==
"printtool" && !spooldir.isEmpty())
536 TQMap<TQString,TQString> options;
537 driver->getOptions(options,
true);
539 options[
"DESIRED_TO"] =
"ps";
540 options[
"PRINTER_TYPE"] = ent->comment(2);
541 options[
"PS_SEND_EOF"] =
"NO";
542 if (!checkGsDriver(options[
"GSDEVICE"]))
544 TQString resol(options[
"RESOLUTION"]), color(options[
"COLOR"]);
546 ent->m_comment = TQString::fromLatin1(
"##PRINTTOOL3## %1 %2 %3 %4 {} {%5} %6 {}").arg(options[
"PRINTER_TYPE"]).arg(options[
"GSDEVICE"]).arg((resol.isEmpty() ? TQString::fromLatin1(
"NAxNA") : resol)).arg(options[
"PAPERSIZE"]).arg(driver->name()).arg((color.isEmpty() ? TQString::fromLatin1(
"Default") : color.right(color.length()-15)));
547 ent->m_args[
"if"] = spooldir+TQString::fromLatin1(
"/filter");
548 if (!writePrinters())
551 TQCString cmd =
"cp ";
552 cmd += TQFile::encodeName(TDEProcess::quote(driverDirectory()+
"/master-filter"));
554 cmd += TQFile::encodeName(TDEProcess::quote(spooldir +
"/filter"));
555 if (system(cmd.data()) == 0 &&
556 savePrinttoolCfgFile(driverDirectory()+
"/general.cfg.in",spooldir,options) &&
557 savePrinttoolCfgFile(driverDirectory()+
"/postscript.cfg.in",spooldir,options) &&
558 savePrinttoolCfgFile(driverDirectory()+
"/textonly.cfg.in",spooldir,options))
560 setErrorMsg(i18n(
"Unable to write driver associated files in spool directory."));
565 bool KMLpdManager::createPrinttoolEntry(KMPrinter *printer, PrintcapEntry *entry)
567 KURL dev(printer->device());
568 TQString prot = dev.protocol(), sd(entry->arg(
"sd"));
569 entry->m_comment = TQString::fromLatin1(
"##PRINTTOOL3## %1").arg(ptPrinterType(printer));
570 if (prot ==
"smb" || prot ==
"ncp" || prot ==
"socket")
572 entry->m_args[
"af"] = sd+TQString::fromLatin1(
"/acct");
573 QFile f(sd+TQString::fromLatin1(
"/.config"));
574 if (f.open(IO_WriteOnly))
577 if (prot ==
"socket")
579 t <<
"printer_ip=" << dev.host() << endl;
580 t <<
"port=" << dev.port() << endl;
581 entry->m_args[
"if"] = driverDirectory()+TQString::fromLatin1(
"/directprint");
583 else if (prot ==
"smb")
585 QStringList l = TQStringList::split(
'/',dev.path(),
false);
588 t <<
"share='\\\\" << l[0] <<
'\\' << l[1] <<
'\'' << endl;
590 else if (l.count() == 1)
592 t <<
"share='\\\\" << dev.host() <<
'\\' << l[0] <<
'\'' << endl;
594 t <<
"hostip=" << endl;
595 t <<
"user='" << dev.user() <<
'\'' << endl;
596 t <<
"password='" << dev.pass() <<
'\'' << endl;
597 t <<
"workgroup='" << (l.count() == 2 ? dev.host() : TQString::fromLatin1(
"")) <<
'\'' << endl;
598 entry->m_args[
"if"] = driverDirectory()+TQString::fromLatin1(
"/smbprint");
600 else if (prot ==
"ncp")
602 t <<
"server=" << dev.host() << endl;
603 t <<
"queue=" << dev.path().replace(
"/",TQString::fromLatin1(
"")) << endl;
604 t <<
"user=" << dev.user() << endl;
605 t <<
"password=" << dev.pass() << endl;
606 entry->m_args[
"if"] = driverDirectory()+TQString::fromLatin1(
"/ncpprint");
610 entry->m_args[
"lp"] = TQString::fromLatin1(
"/dev/null");
612 else if (prot !=
"lpd")
613 entry->m_args[
"lp"] = dev.path();
617 bool KMLpdManager::createSpooldir(PrintcapEntry *entry)
620 if (entry->arg(
"sd").isEmpty())
621 entry->m_args[
"sd"] = TQString::fromLatin1(
"/var/spool/lpd/")+entry->m_name;
622 TQString sd = entry->arg(
"sd");
623 if (!TDEStandardDirs::exists(sd))
625 if (!TDEStandardDirs::makeDir(sd,0750))
627 struct passwd *lp_pw = getpwnam(
"lp");
628 if (lp_pw && chown(TQFile::encodeName(sd),lp_pw->pw_uid,lp_pw->pw_gid) != 0)
634 bool KMLpdManager::validateDbDriver(KMDBEntry *entry)
636 PrinttoolEntry *ptentry = findPrinttoolEntry(entry->modelname);
637 return (ptentry && checkGsDriver(ptentry->m_gsdriver));
642 TQString ptPrinterType(KMPrinter *p)
644 TQString type, prot = p->device().protocol();
645 if (prot ==
"lpd") type =
"REMOTE";
646 else if (prot ==
"smb") type =
"SMB";
647 else if (prot ==
"ncp") type =
"NCP";
648 else if (prot ==
"socket") type =
"DIRECT";