• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdeprint
 

kdeprint

  • kdeprint
  • cups
cupsaddsmb2.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License version 2 as published by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB. If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  **/
19 
20 #include "cupsaddsmb2.h"
21 #include "cupsinfos.h"
22 #include "sidepixmap.h"
23 
24 #include <tqtimer.h>
25 #include <tqprogressbar.h>
26 #include <tqlabel.h>
27 #include <tqlayout.h>
28 #include <tqlineedit.h>
29 #include <klocale.h>
30 #include <kmessagebox.h>
31 #include <tqmessagebox.h>
32 #include <tqfile.h>
33 #include <kio/passdlg.h>
34 #include <kdebug.h>
35 #include <kseparator.h>
36 #include <kactivelabel.h>
37 #include <tqwhatsthis.h>
38 #include <kpushbutton.h>
39 #include <kstdguiitem.h>
40 
41 #include <cups/cups.h>
42 #include <ctype.h>
43 
44 CupsAddSmb::CupsAddSmb(TQWidget *parent, const char *name)
45 : KDialog(parent, name)
46 {
47  m_state = None;
48  m_status = false;
49  m_actionindex = 0;
50  connect(&m_proc, TQT_SIGNAL(receivedStdout(KProcess*,char*,int)), TQT_SLOT(slotReceived(KProcess*,char*,int)));
51  connect(&m_proc, TQT_SIGNAL(receivedStderr(KProcess*,char*,int)), TQT_SLOT(slotReceived(KProcess*,char*,int)));
52  connect(&m_proc, TQT_SIGNAL(processExited(KProcess*)), TQT_SLOT(slotProcessExited(KProcess*)));
53 
54  m_side = new SidePixmap(this);
55  m_doit = new TQPushButton(i18n("&Export"), this);
56  m_cancel = new KPushButton(KStdGuiItem::cancel(), this);
57  connect(m_cancel, TQT_SIGNAL(clicked()), TQT_SLOT(reject()));
58  connect(m_doit, TQT_SIGNAL(clicked()), TQT_SLOT(slotActionClicked()));
59  m_bar = new TQProgressBar(this);
60  m_text = new KActiveLabel(this);
61  TQLabel *m_title = new TQLabel(i18n("Export Printer Driver to Windows Clients"), this);
62  setCaption(m_title->text());
63  TQFont f(m_title->font());
64  f.setBold(true);
65  m_title->setFont(f);
66  KSeparator *m_sep = new KSeparator(Qt::Horizontal, this);
67  m_textinfo = new TQLabel( this );
68  m_logined = new TQLineEdit( this );
69  m_passwded = new TQLineEdit( this );
70  m_passwded->setEchoMode( TQLineEdit::Password );
71  m_servered = new TQLineEdit( this );
72  TQLabel *m_loginlab = new TQLabel( i18n( "&Username:" ), this );
73  TQLabel *m_serverlab = new TQLabel( i18n( "&Samba server:" ), this );
74  TQLabel *m_passwdlab = new TQLabel( i18n( "&Password:" ), this );
75  m_loginlab->setBuddy( m_logined );
76  m_serverlab->setBuddy( m_servered );
77  m_passwdlab->setBuddy( m_passwded );
78 
79  TQString txt = i18n( "<p><b>Samba server</b></p>"
80  "Adobe Windows PostScript driver files plus the CUPS printer PPD will be "
81  "exported to the <tt>[print$]</tt> special share of the Samba server (to change "
82  "the source CUPS server, use the <nobr><i>Configure Manager -> CUPS server</i></nobr> first). "
83  "The <tt>[print$]</tt> share must exist on the Samba side prior to clicking the "
84  "<b>Export</b> button below." );
85  TQWhatsThis::add( m_serverlab, txt );
86  TQWhatsThis::add( m_servered, txt );
87 
88  txt = i18n( "<p><b>Samba username</b></p>"
89  "User needs to have write access to the <tt>[print$]</tt> share on the Samba server. "
90  "<tt>[print$]</tt> holds printer drivers prepared for download to Windows clients. "
91  "This dialog does not work for Samba servers configured with <tt>security = share</tt> "
92  "(but works fine with <tt>security = user</tt>)." );
93  TQWhatsThis::add( m_loginlab, txt );
94  TQWhatsThis::add( m_logined, txt );
95 
96  txt = i18n( "<p><b>Samba password</b></p>"
97  "The Samba setting <tt>encrypt passwords = yes</tt> "
98  "(default) requires prior use of <tt>smbpasswd -a [username]</tt> command, "
99  "to create an encrypted Samba password and have Samba recognize it." );
100  TQWhatsThis::add( m_passwdlab, txt );
101  TQWhatsThis::add( m_passwded, txt );
102 
103  TQHBoxLayout *l0 = new TQHBoxLayout(this, 10, 10);
104  TQVBoxLayout *l1 = new TQVBoxLayout(0, 0, 10);
105  l0->addWidget(m_side);
106  l0->addLayout(l1);
107  l1->addWidget(m_title);
108  l1->addWidget(m_sep);
109  l1->addWidget(m_text);
110  TQGridLayout *l3 = new TQGridLayout( 0, 3, 2, 0, 10 );
111  l1->addLayout( TQT_TQLAYOUT(l3) );
112  l3->addWidget( m_loginlab, 1, 0 );
113  l3->addWidget( m_passwdlab, 2, 0 );
114  l3->addWidget( m_serverlab, 0, 0 );
115  l3->addWidget( m_logined, 1, 1 );
116  l3->addWidget( m_passwded, 2, 1 );
117  l3->addWidget( m_servered, 0, 1 );
118  l3->setColStretch( 1, 1 );
119  l1->addSpacing( 10 );
120  l1->addWidget(m_bar);
121  l1->addWidget( m_textinfo );
122  l1->addSpacing(30);
123  TQHBoxLayout *l2 = new TQHBoxLayout(0, 0, 10);
124  l1->addLayout(l2);
125  l2->addStretch(1);
126  l2->addWidget(m_doit);
127  l2->addWidget(m_cancel);
128 
129  m_logined->setText( CupsInfos::self()->login() );
130  m_passwded->setText( CupsInfos::self()->password() );
131  m_servered->setText( cupsServer() );
132 
133  setMinimumHeight(400);
134 }
135 
136 CupsAddSmb::~CupsAddSmb()
137 {
138 }
139 
140 void CupsAddSmb::slotActionClicked()
141 {
142  if (m_state == None)
143  doExport();
144  else if (m_proc.isRunning())
145  m_proc.kill();
146 }
147 
148 void CupsAddSmb::slotReceived(KProcess*, char *buf, int buflen)
149 {
150  TQString line;
151  int index(0);
152  bool partial(false);
153  static bool incomplete(false);
154 
155  kdDebug(500) << "slotReceived()" << endl;
156  while (1)
157  {
158  // read a line
159  line = TQString::fromLatin1("");
160  partial = true;
161  while (index < buflen)
162  {
163  TQChar c(buf[index++]);
164  if (c == '\n')
165  {
166  partial = false;
167  break;
168  }
169  else if (c.isPrint())
170  line += c;
171  }
172 
173  if (line.isEmpty())
174  {
175  kdDebug(500) << "NOTHING TO READ" << endl;
176  return;
177  }
178 
179  kdDebug(500) << "ANSWER = " << line << " (END = " << line.length() << ")" << endl;
180  if (!partial)
181  {
182  if (incomplete && m_buffer.count() > 0)
183  m_buffer[m_buffer.size()-1].append(line);
184  else
185  m_buffer << line;
186  incomplete = false;
187  kdDebug(500) << "COMPLETE LINE READ (" << m_buffer.count() << ")" << endl;
188  }
189  else
190  {
191  if (line.startsWith("smb:") || line.startsWith("rpcclient $"))
192  {
193  kdDebug(500) << "END OF ACTION" << endl;
194  checkActionStatus();
195  if (m_status)
196  nextAction();
197  else
198  {
199  // quit program
200  kdDebug(500) << "EXITING PROGRAM..." << endl;
201  m_proc.writeStdin("quit\n", 5);
202  kdDebug(500) << "SENT" << endl;
203  }
204  return;
205  }
206  else
207  {
208  if (incomplete && m_buffer.count() > 0)
209  m_buffer[m_buffer.size()-1].append(line);
210  else
211  m_buffer << line;
212  incomplete = true;
213  kdDebug(500) << "INCOMPLETE LINE READ (" << m_buffer.count() << ")" << endl;
214  }
215  }
216  }
217 }
218 
219 void CupsAddSmb::checkActionStatus()
220 {
221  m_status = false;
222  // when checking the status, we need to take into account the
223  // echo of the command in the output buffer.
224  switch (m_state)
225  {
226  case None:
227  case Start:
228  m_status = true;
229  break;
230  case Copy:
231  m_status = (m_buffer.count() == 0);
232  break;
233  case MkDir:
234  m_status = (m_buffer.count() == 1 || m_buffer[1].find("ERRfilexists") != -1);
235  break;
236  case AddDriver:
237  case AddPrinter:
238  m_status = (m_buffer.count() == 1 || !m_buffer[1].startsWith("result"));
239  break;
240  }
241  kdDebug(500) << "ACTION STATUS = " << m_status << endl;
242 }
243 
244 void CupsAddSmb::nextAction()
245 {
246  if (m_actionindex < (int)(m_actions.count()))
247  TQTimer::singleShot(1, this, TQT_SLOT(doNextAction()));
248 }
249 
250 void CupsAddSmb::doNextAction()
251 {
252  m_buffer.clear();
253  m_state = None;
254  if (m_proc.isRunning())
255  {
256  TQCString s = m_actions[m_actionindex++].latin1();
257  m_bar->setProgress(m_bar->progress()+1);
258  kdDebug(500) << "NEXT ACTION = " << s << endl;
259  if (s == "quit")
260  {
261  // do nothing
262  }
263  else if (s == "mkdir")
264  {
265  m_state = MkDir;
266  //m_text->setText(i18n("Creating directory %1").arg(m_actions[m_actionindex]));
267  m_textinfo->setText(i18n("Creating folder %1").arg(m_actions[m_actionindex]));
268  s.append(" ").append(m_actions[m_actionindex].latin1());
269  m_actionindex++;
270  }
271  else if (s == "put")
272  {
273  m_state = Copy;
274  //m_text->setText(i18n("Uploading %1").arg(m_actions[m_actionindex+1]));
275  m_textinfo->setText(i18n("Uploading %1").arg(m_actions[m_actionindex+1]));
276  s.append(" ").append(TQFile::encodeName(m_actions[m_actionindex]).data()).append(" ").append(m_actions[m_actionindex+1].latin1());
277  m_actionindex += 2;
278  }
279  else if (s == "adddriver")
280  {
281  m_state = AddDriver;
282  //m_text->setText(i18n("Installing driver for %1").arg(m_actions[m_actionindex]));
283  m_textinfo->setText(i18n("Installing driver for %1").arg(m_actions[m_actionindex]));
284  s.append(" \"").append(m_actions[m_actionindex].latin1()).append("\" \"").append(m_actions[m_actionindex+1].latin1()).append("\"");
285  m_actionindex += 2;
286  }
287  else if (s == "addprinter" || s == "setdriver")
288  {
289  m_state = AddPrinter;
290  //m_text->setText(i18n("Installing printer %1").arg(m_actions[m_actionindex]));
291  m_textinfo->setText(i18n("Installing printer %1").arg(m_actions[m_actionindex]));
292  TQCString dest = m_actions[m_actionindex].local8Bit();
293  if (s == "addprinter")
294  s.append(" ").append(dest).append(" ").append(dest).append(" \"").append(dest).append("\" \"\"");
295  else
296  s.append(" ").append(dest).append(" ").append(dest);
297  m_actionindex++;
298  }
299  else
300  {
301  kdDebug(500) << "ACTION = unknown action" << endl;
302  m_proc.kill();
303  return;
304  }
305  // send action
306  kdDebug(500) << "ACTION = " << s << endl;
307  s.append("\n");
308  m_proc.writeStdin(s.data(), s.length());
309  }
310 }
311 
312 void CupsAddSmb::slotProcessExited(KProcess*)
313 {
314  kdDebug(500) << "PROCESS EXITED (" << m_state << ")" << endl;
315  if (m_proc.normalExit() && m_state != Start && m_status)
316  {
317  // last process went OK. If it was smbclient, then switch to rpcclient
318  if (tqstrncmp(m_proc.args().first(), "smbclient", 9) == 0)
319  {
320  doInstall();
321  return;
322  }
323  else
324  {
325  m_doit->setEnabled(false);
326  m_cancel->setEnabled(true);
327  m_cancel->setText(i18n("&Close"));
328  m_cancel->setDefault(true);
329  m_cancel->setFocus();
330  m_logined->setEnabled( true );
331  m_servered->setEnabled( true );
332  m_passwded->setEnabled( true );
333  m_text->setText(i18n("Driver successfully exported."));
334  m_bar->reset();
335  m_textinfo->setText( TQString::null );
336  return;
337  }
338  }
339 
340  if (m_proc.normalExit())
341  {
342  showError(
343  i18n("Operation failed. Possible reasons are: permission denied "
344  "or invalid Samba configuration (see <a href=\"man:/cupsaddsmb\">"
345  "cupsaddsmb</a> manual page for detailed information, you need "
346  "<a href=\"http://www.cups.org\">CUPS</a> version 1.1.11 or higher). "
347  "You may want to try again with another login/password."));
348 
349  }
350  else
351  {
352  showError(i18n("Operation aborted (process killed)."));
353  }
354 }
355 
356 void CupsAddSmb::showError(const TQString& msg)
357 {
358  m_text->setText(i18n("<h3>Operation failed.</h3><p>%1</p>").arg(msg));
359  m_cancel->setEnabled(true);
360  m_logined->setEnabled( true );
361  m_servered->setEnabled( true );
362  m_passwded->setEnabled( true );
363  m_doit->setText(i18n("&Export"));
364  m_state = None;
365 }
366 
367 bool CupsAddSmb::exportDest(const TQString &dest, const TQString& datadir)
368 {
369  CupsAddSmb dlg;
370  dlg.m_dest = dest;
371  dlg.m_datadir = datadir;
372  dlg.m_text->setText(
373  i18n( "You are about to prepare the <b>%1</b> driver to be "
374  "shared out to Windows clients through Samba. This operation "
375  "requires the <a href=\"http://www.adobe.com/products/printerdrivers/main.html\">Adobe PostScript Driver</a>, a recent version of "
376  "Samba 2.2.x and a running SMB service on the target server. "
377  "Click <b>Export</b> to start the operation. Read the <a href=\"man:/cupsaddsmb\">cupsaddsmb</a> "
378  "manual page in Konqueror or type <tt>man cupsaddsmb</tt> in a "
379  "console window to learn more about this functionality." ).arg( dest ) );
380  dlg.exec();
381  return dlg.m_status;
382 }
383 
384 bool CupsAddSmb::doExport()
385 {
386  m_status = false;
387  m_state = None;
388 
389  if (!TQFile::exists(m_datadir+"/drivers/ADOBEPS5.DLL") ||
390  !TQFile::exists(m_datadir+"/drivers/ADOBEPS4.DRV"))
391  {
392  showError(
393  i18n("Some driver files are missing. You can get them on "
394  "<a href=\"http://www.adobe.com\">Adobe</a> web site. "
395  "See <a href=\"man:/cupsaddsmb\">cupsaddsmb</a> manual "
396  "page for more details (you need <a href=\"http://www.cups.org\">CUPS</a> "
397  "version 1.1.11 or higher)."));
398  return false;
399  }
400 
401  m_bar->setTotalSteps(18);
402  m_bar->setProgress(0);
403  //m_text->setText(i18n("<p>Preparing to upload driver to host <b>%1</b>").arg(m_servered->text()));
404  m_textinfo->setText(i18n("Preparing to upload driver to host %1").arg(m_servered->text()));
405  m_cancel->setEnabled(false);
406  m_logined->setEnabled( false );
407  m_servered->setEnabled( false );
408  m_passwded->setEnabled( false );
409  m_doit->setText(i18n("&Abort"));
410 
411  const char *ppdfile;
412 
413  if ((ppdfile = cupsGetPPD(m_dest.local8Bit())) == NULL)
414  {
415  showError(i18n("The driver for printer <b>%1</b> could not be found.").arg(m_dest));
416  return false;
417  }
418 
419  m_actions.clear();
420  m_actions << "mkdir" << "W32X86";
421  m_actions << "put" << ppdfile << "W32X86/"+m_dest+".PPD";
422  m_actions << "put" << m_datadir+"/drivers/ADOBEPS5.DLL" << "W32X86/ADOBEPS5.DLL";
423  m_actions << "put" << m_datadir+"/drivers/ADOBEPSU.DLL" << "W32X86/ADOBEPSU.DLL";
424  m_actions << "put" << m_datadir+"/drivers/ADOBEPSU.HLP" << "W32X86/ADOBEPSU.HLP";
425  m_actions << "mkdir" << "WIN40";
426  m_actions << "put" << ppdfile << "WIN40/"+m_dest+".PPD";
427  m_actions << "put" << m_datadir+"/drivers/ADFONTS.MFM" << "WIN40/ADFONTS.MFM";
428  m_actions << "put" << m_datadir+"/drivers/ADOBEPS4.DRV" << "WIN40/ADOBEPS4.DRV";
429  m_actions << "put" << m_datadir+"/drivers/ADOBEPS4.HLP" << "WIN40/ADOBEPS4.HLP";
430  m_actions << "put" << m_datadir+"/drivers/DEFPRTR2.PPD" << "WIN40/DEFPRTR2.PPD";
431  m_actions << "put" << m_datadir+"/drivers/ICONLIB.DLL" << "WIN40/ICONLIB.DLL";
432  m_actions << "put" << m_datadir+"/drivers/PSMON.DLL" << "WIN40/PSMON.DLL";
433  m_actions << "quit";
434 
435  m_proc.clearArguments();
436  m_proc << "smbclient" << TQString::fromLatin1("//")+m_servered->text()+"/print$";
437  return startProcess();
438 }
439 
440 bool CupsAddSmb::doInstall()
441 {
442  m_status = false;
443  m_state = None;
444 
445  m_actions.clear();
446  m_actions << "adddriver" << "Windows NT x86" << m_dest+":ADOBEPS5.DLL:"+m_dest+".PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL";
447  // seems to be wrong with newer versions of Samba
448  //m_actions << "addprinter" << m_dest;
449  m_actions << "adddriver" << "Windows 4.0" << m_dest+":ADOBEPS4.DRV:"+m_dest+".PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL";
450  // seems to be ok with newer versions of Samba
451  m_actions << "setdriver" << m_dest;
452  m_actions << "quit";
453 
454  //m_text->setText(i18n("Preparing to install driver on host <b>%1</b>").arg(m_servered->text()));
455  m_textinfo->setText(i18n("Preparing to install driver on host %1").arg(m_servered->text()));
456 
457  m_proc.clearArguments();
458  m_proc << "rpcclient" << m_servered->text();
459  return startProcess();
460 }
461 
462 bool CupsAddSmb::startProcess()
463 {
464  m_proc << "-d" << "0" << "-N" << "-U";
465  if (m_passwded->text().isEmpty())
466  m_proc << m_logined->text();
467  else
468  m_proc << m_logined->text()+"%"+m_passwded->text();
469  m_state = Start;
470  m_actionindex = 0;
471  m_buffer.clear();
472  kdDebug(500) << "PROCESS STARTED = " << m_proc.args()[0] << endl;
473  return m_proc.start(KProcess::NotifyOnExit, KProcess::All);
474 }
475 
476 #include "cupsaddsmb2.moc"

kdeprint

Skip menu "kdeprint"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdeprint

Skip menu "kdeprint"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdeprint by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |