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

tdeprint

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

tdeprint

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

tdeprint

Skip menu "tdeprint"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeprint by doxygen 1.9.4
This website is maintained by Timothy Pearson.