kdeprint Library API Documentation

cupsaddsmb2.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., 59 Temple Place - Suite 330, 00017 * Boston, MA 02111-1307, USA. 00018 **/ 00019 00020 #include "cupsaddsmb2.h" 00021 #include "cupsinfos.h" 00022 #include "sidepixmap.h" 00023 00024 #include <qtimer.h> 00025 #include <qprogressbar.h> 00026 #include <qlabel.h> 00027 #include <qlayout.h> 00028 #include <qlineedit.h> 00029 #include <klocale.h> 00030 #include <kmessagebox.h> 00031 #include <qmessagebox.h> 00032 #include <qfile.h> 00033 #include <kio/passdlg.h> 00034 #include <kdebug.h> 00035 #include <kseparator.h> 00036 #include <kactivelabel.h> 00037 #include <qwhatsthis.h> 00038 #include <kpushbutton.h> 00039 #include <kstdguiitem.h> 00040 00041 #include <cups/cups.h> 00042 #include <ctype.h> 00043 00044 CupsAddSmb::CupsAddSmb(QWidget *parent, const char *name) 00045 : KDialog(parent, name) 00046 { 00047 m_state = None; 00048 m_status = false; 00049 m_actionindex = 0; 00050 connect(&m_proc, SIGNAL(receivedStdout(KProcess*,char*,int)), SLOT(slotReceived(KProcess*,char*,int))); 00051 connect(&m_proc, SIGNAL(receivedStderr(KProcess*,char*,int)), SLOT(slotReceived(KProcess*,char*,int))); 00052 connect(&m_proc, SIGNAL(processExited(KProcess*)), SLOT(slotProcessExited(KProcess*))); 00053 00054 m_side = new SidePixmap(this); 00055 m_doit = new QPushButton(i18n("&Export"), this); 00056 m_cancel = new KPushButton(KStdGuiItem::cancel(), this); 00057 connect(m_cancel, SIGNAL(clicked()), SLOT(reject())); 00058 connect(m_doit, SIGNAL(clicked()), SLOT(slotActionClicked())); 00059 m_bar = new QProgressBar(this); 00060 m_text = new KActiveLabel(this); 00061 QLabel *m_title = new QLabel(i18n("Export printer driver to Windows clients"), this); 00062 setCaption(m_title->text()); 00063 QFont f(m_title->font()); 00064 f.setBold(true); 00065 m_title->setFont(f); 00066 KSeparator *m_sep = new KSeparator(Qt::Horizontal, this); 00067 m_textinfo = new QLabel( this ); 00068 m_logined = new QLineEdit( this ); 00069 m_passwded = new QLineEdit( this ); 00070 m_passwded->setEchoMode( QLineEdit::Password ); 00071 m_servered = new QLineEdit( this ); 00072 QLabel *m_loginlab = new QLabel( i18n( "&Username:" ), this ); 00073 QLabel *m_serverlab = new QLabel( i18n( "&Samba server:" ), this ); 00074 QLabel *m_passwdlab = new QLabel( i18n( "&Password:" ), this ); 00075 m_loginlab->setBuddy( m_logined ); 00076 m_serverlab->setBuddy( m_servered ); 00077 m_passwdlab->setBuddy( m_passwded ); 00078 00079 QString txt = i18n( "<p><b>Samba server</b></p>" 00080 "Adobe Windows PostScript driver files plus the CUPS printer PPD will be " 00081 "exported to the <tt>[print$]</tt> special share of the Samba server (to change " 00082 "the source CUPS server, use the <nobr><i>Configure Manager -> CUPS server</i></nobr> first). " 00083 "The <tt>[print$]</tt> share must exist on the Samba side prior to clicking the " 00084 "<b>Export</b> button below." ); 00085 QWhatsThis::add( m_serverlab, txt ); 00086 QWhatsThis::add( m_servered, txt ); 00087 00088 txt = i18n( "<p><b>Samba username</b></p>" 00089 "User needs to have write access to the <tt>[print$]</tt> share on the Samba server. " 00090 "<tt>[print$]</tt> holds printer drivers prepared for download to Windows clients. " 00091 "This dialog does not work for Samba servers configured with <tt>security = share</tt> " 00092 "(but works fine with <tt>security = user</tt>)." ); 00093 QWhatsThis::add( m_loginlab, txt ); 00094 QWhatsThis::add( m_logined, txt ); 00095 00096 txt = i18n( "<p><b>Samba password</b></p>" 00097 "The Samba setting <tt>encrypt passwords = yes</tt> " 00098 "(default) requires prior use of <tt>smbpasswd -a [username]</tt> command, " 00099 "to create an encrypted Samba password and have Samba recognize it." ); 00100 QWhatsThis::add( m_passwdlab, txt ); 00101 QWhatsThis::add( m_passwded, txt ); 00102 00103 QHBoxLayout *l0 = new QHBoxLayout(this, 10, 10); 00104 QVBoxLayout *l1 = new QVBoxLayout(0, 0, 10); 00105 l0->addWidget(m_side); 00106 l0->addLayout(l1); 00107 l1->addWidget(m_title); 00108 l1->addWidget(m_sep); 00109 l1->addWidget(m_text); 00110 QGridLayout *l3 = new QGridLayout( 0, 3, 2, 0, 10 ); 00111 l1->addLayout( l3 ); 00112 l3->addWidget( m_loginlab, 1, 0 ); 00113 l3->addWidget( m_passwdlab, 2, 0 ); 00114 l3->addWidget( m_serverlab, 0, 0 ); 00115 l3->addWidget( m_logined, 1, 1 ); 00116 l3->addWidget( m_passwded, 2, 1 ); 00117 l3->addWidget( m_servered, 0, 1 ); 00118 l3->setColStretch( 1, 1 ); 00119 l1->addSpacing( 10 ); 00120 l1->addWidget(m_bar); 00121 l1->addWidget( m_textinfo ); 00122 l1->addSpacing(30); 00123 QHBoxLayout *l2 = new QHBoxLayout(0, 0, 10); 00124 l1->addLayout(l2); 00125 l2->addStretch(1); 00126 l2->addWidget(m_doit); 00127 l2->addWidget(m_cancel); 00128 00129 m_logined->setText( CupsInfos::self()->login() ); 00130 m_passwded->setText( CupsInfos::self()->password() ); 00131 m_servered->setText( cupsServer() ); 00132 00133 setMinimumHeight(400); 00134 } 00135 00136 CupsAddSmb::~CupsAddSmb() 00137 { 00138 } 00139 00140 void CupsAddSmb::slotActionClicked() 00141 { 00142 if (m_state == None) 00143 doExport(); 00144 else if (m_proc.isRunning()) 00145 m_proc.kill(); 00146 } 00147 00148 void CupsAddSmb::slotReceived(KProcess*, char *buf, int buflen) 00149 { 00150 QString line; 00151 int index(0); 00152 bool partial(false); 00153 static bool incomplete(false); 00154 00155 kdDebug(500) << "slotReceived()" << endl; 00156 while (1) 00157 { 00158 // read a line 00159 line = QString::fromLatin1(""); 00160 partial = true; 00161 while (index < buflen) 00162 { 00163 QChar c(buf[index++]); 00164 if (c == '\n') 00165 { 00166 partial = false; 00167 break; 00168 } 00169 else if (c.isPrint()) 00170 line += c; 00171 } 00172 00173 if (line.isEmpty()) 00174 { 00175 kdDebug(500) << "NOTHING TO READ" << endl; 00176 return; 00177 } 00178 00179 kdDebug(500) << "ANSWER = " << line << " (END = " << line.length() << ")" << endl; 00180 if (!partial) 00181 { 00182 if (incomplete && m_buffer.count() > 0) 00183 m_buffer[m_buffer.size()-1].append(line); 00184 else 00185 m_buffer << line; 00186 incomplete = false; 00187 kdDebug(500) << "COMPLETE LINE READ (" << m_buffer.count() << ")" << endl; 00188 } 00189 else 00190 { 00191 if (line.startsWith("smb:") || line.startsWith("rpcclient $")) 00192 { 00193 kdDebug(500) << "END OF ACTION" << endl; 00194 checkActionStatus(); 00195 if (m_status) 00196 nextAction(); 00197 else 00198 { 00199 // quit program 00200 kdDebug(500) << "EXITING PROGRAM..." << endl; 00201 m_proc.writeStdin("quit\n", 5); 00202 kdDebug(500) << "SENT" << endl; 00203 } 00204 return; 00205 } 00206 else 00207 { 00208 if (incomplete && m_buffer.count() > 0) 00209 m_buffer[m_buffer.size()-1].append(line); 00210 else 00211 m_buffer << line; 00212 incomplete = true; 00213 kdDebug(500) << "INCOMPLETE LINE READ (" << m_buffer.count() << ")" << endl; 00214 } 00215 } 00216 } 00217 } 00218 00219 void CupsAddSmb::checkActionStatus() 00220 { 00221 m_status = false; 00222 // when checking the status, we need to take into account the 00223 // echo of the command in the output buffer. 00224 switch (m_state) 00225 { 00226 case None: 00227 case Start: 00228 m_status = true; 00229 break; 00230 case Copy: 00231 m_status = (m_buffer.count() == 0); 00232 break; 00233 case MkDir: 00234 m_status = (m_buffer.count() == 1 || m_buffer[1].find("ERRfilexists") != -1); 00235 break; 00236 case AddDriver: 00237 case AddPrinter: 00238 m_status = (m_buffer.count() == 1 || !m_buffer[1].startsWith("result")); 00239 break; 00240 } 00241 kdDebug(500) << "ACTION STATUS = " << m_status << endl; 00242 } 00243 00244 void CupsAddSmb::nextAction() 00245 { 00246 if (m_actionindex < (int)(m_actions.count())) 00247 QTimer::singleShot(1, this, SLOT(doNextAction())); 00248 } 00249 00250 void CupsAddSmb::doNextAction() 00251 { 00252 m_buffer.clear(); 00253 m_state = None; 00254 if (m_proc.isRunning()) 00255 { 00256 QCString s = m_actions[m_actionindex++].latin1(); 00257 m_bar->setProgress(m_bar->progress()+1); 00258 kdDebug(500) << "NEXT ACTION = " << s << endl; 00259 if (s == "quit") 00260 { 00261 // do nothing 00262 } 00263 else if (s == "mkdir") 00264 { 00265 m_state = MkDir; 00266 //m_text->setText(i18n("Creating directory %1").arg(m_actions[m_actionindex])); 00267 m_textinfo->setText(i18n("Creating folder %1").arg(m_actions[m_actionindex])); 00268 s.append(" ").append(m_actions[m_actionindex].latin1()); 00269 m_actionindex++; 00270 } 00271 else if (s == "put") 00272 { 00273 m_state = Copy; 00274 //m_text->setText(i18n("Uploading %1").arg(m_actions[m_actionindex+1])); 00275 m_textinfo->setText(i18n("Uploading %1").arg(m_actions[m_actionindex+1])); 00276 s.append(" ").append(QFile::encodeName(m_actions[m_actionindex]).data()).append(" ").append(m_actions[m_actionindex+1].latin1()); 00277 m_actionindex += 2; 00278 } 00279 else if (s == "adddriver") 00280 { 00281 m_state = AddDriver; 00282 //m_text->setText(i18n("Installing driver for %1").arg(m_actions[m_actionindex])); 00283 m_textinfo->setText(i18n("Installing driver for %1").arg(m_actions[m_actionindex])); 00284 s.append(" \"").append(m_actions[m_actionindex].latin1()).append("\" \"").append(m_actions[m_actionindex+1].latin1()).append("\""); 00285 m_actionindex += 2; 00286 } 00287 else if (s == "addprinter" || s == "setdriver") 00288 { 00289 m_state = AddPrinter; 00290 //m_text->setText(i18n("Installing printer %1").arg(m_actions[m_actionindex])); 00291 m_textinfo->setText(i18n("Installing printer %1").arg(m_actions[m_actionindex])); 00292 QCString dest = m_actions[m_actionindex].local8Bit(); 00293 if (s == "addprinter") 00294 s.append(" ").append(dest).append(" ").append(dest).append(" \"").append(dest).append("\" \"\""); 00295 else 00296 s.append(" ").append(dest).append(" ").append(dest); 00297 m_actionindex++; 00298 } 00299 else 00300 { 00301 kdDebug(500) << "ACTION = unknown action" << endl; 00302 m_proc.kill(); 00303 return; 00304 } 00305 // send action 00306 kdDebug(500) << "ACTION = " << s << endl; 00307 s.append("\n"); 00308 m_proc.writeStdin(s.data(), s.length()); 00309 } 00310 } 00311 00312 void CupsAddSmb::slotProcessExited(KProcess*) 00313 { 00314 kdDebug(500) << "PROCESS EXITED (" << m_state << ")" << endl; 00315 if (m_proc.normalExit() && m_state != Start && m_status) 00316 { 00317 // last process went OK. If it was smbclient, then switch to rpcclient 00318 if (qstrncmp(m_proc.args().first(), "smbclient", 9) == 0) 00319 { 00320 doInstall(); 00321 return; 00322 } 00323 else 00324 { 00325 m_doit->setEnabled(false); 00326 m_cancel->setEnabled(true); 00327 m_cancel->setText(i18n("&Close")); 00328 m_cancel->setDefault(true); 00329 m_cancel->setFocus(); 00330 m_logined->setEnabled( true ); 00331 m_servered->setEnabled( true ); 00332 m_passwded->setEnabled( true ); 00333 m_text->setText(i18n("Driver successfully exported.")); 00334 m_bar->reset(); 00335 m_textinfo->setText( QString::null ); 00336 return; 00337 } 00338 } 00339 00340 if (m_proc.normalExit()) 00341 { 00342 showError( 00343 i18n("Operation failed. Possible reasons are: permission denied " 00344 "or invalid Samba configuration (see <a href=\"man:/cupsaddsmb\">" 00345 "cupsaddsmb</a> manual page for detailed information, you need " 00346 "<a href=\"http://www.cups.org\">CUPS</a> version 1.1.11 or higher). " 00347 "You may want to try again with another login/password.")); 00348 00349 } 00350 else 00351 { 00352 showError(i18n("Operation aborted (process killed).")); 00353 } 00354 } 00355 00356 void CupsAddSmb::showError(const QString& msg) 00357 { 00358 m_text->setText(i18n("<h3>Operation failed!</h3><p>%1</p>").arg(msg)); 00359 m_cancel->setEnabled(true); 00360 m_logined->setEnabled( true ); 00361 m_servered->setEnabled( true ); 00362 m_passwded->setEnabled( true ); 00363 m_doit->setText(i18n("&Export")); 00364 m_state = None; 00365 } 00366 00367 bool CupsAddSmb::exportDest(const QString &dest, const QString& datadir) 00368 { 00369 CupsAddSmb dlg; 00370 dlg.m_dest = dest; 00371 dlg.m_datadir = datadir; 00372 dlg.m_text->setText( 00373 i18n( "You are about to prepare the <b>%1</b> driver to be " 00374 "shared out to Windows clients through Samba. This operation " 00375 "requires the <a href=\"http://www.adobe.com/products/printerdrivers/main.html\">Adobe PostScript Driver</a>, a recent version of " 00376 "Samba 2.2.x and a running SMB service on the target server. " 00377 "Click <b>Export</b> to start the operation. Read the <a href=\"man:/cupsaddsmb\">cupsaddsmb</a> " 00378 "manual page in Konqueror or type <tt>man cupsaddsmb</tt> in a " 00379 "console window to learn more about this functionality." ).arg( dest ) ); 00380 dlg.exec(); 00381 return dlg.m_status; 00382 } 00383 00384 bool CupsAddSmb::doExport() 00385 { 00386 m_status = false; 00387 m_state = None; 00388 00389 if (!QFile::exists(m_datadir+"/drivers/ADOBEPS5.DLL") || 00390 !QFile::exists(m_datadir+"/drivers/ADOBEPS4.DRV")) 00391 { 00392 showError( 00393 i18n("Some driver files are missing. You can get them on " 00394 "<a href=\"http://www.adobe.com\">Adobe</a> web site. " 00395 "See <a href=\"man:/cupsaddsmb\">cupsaddsmb</a> manual " 00396 "page for more details (you need <a href=\"http://www.cups.org\">CUPS</a> " 00397 "version 1.1.11 or higher).")); 00398 return false; 00399 } 00400 00401 m_bar->setTotalSteps(18); 00402 m_bar->setProgress(0); 00403 //m_text->setText(i18n("<p>Preparing to upload driver to host <b>%1</b>").arg(m_servered->text())); 00404 m_textinfo->setText(i18n("Preparing to upload driver to host %1").arg(m_servered->text())); 00405 m_cancel->setEnabled(false); 00406 m_logined->setEnabled( false ); 00407 m_servered->setEnabled( false ); 00408 m_passwded->setEnabled( false ); 00409 m_doit->setText(i18n("&Abort")); 00410 00411 const char *ppdfile; 00412 00413 if ((ppdfile = cupsGetPPD(m_dest.local8Bit())) == NULL) 00414 { 00415 showError(i18n("The driver for printer <b>%1</b> could not be found.").arg(m_dest)); 00416 return false; 00417 } 00418 00419 m_actions.clear(); 00420 m_actions << "mkdir" << "W32X86"; 00421 m_actions << "put" << ppdfile << "W32X86/"+m_dest+".PPD"; 00422 m_actions << "put" << m_datadir+"/drivers/ADOBEPS5.DLL" << "W32X86/ADOBEPS5.DLL"; 00423 m_actions << "put" << m_datadir+"/drivers/ADOBEPSU.DLL" << "W32X86/ADOBEPSU.DLL"; 00424 m_actions << "put" << m_datadir+"/drivers/ADOBEPSU.HLP" << "W32X86/ADOBEPSU.HLP"; 00425 m_actions << "mkdir" << "WIN40"; 00426 m_actions << "put" << ppdfile << "WIN40/"+m_dest+".PPD"; 00427 m_actions << "put" << m_datadir+"/drivers/ADFONTS.MFM" << "WIN40/ADFONTS.MFM"; 00428 m_actions << "put" << m_datadir+"/drivers/ADOBEPS4.DRV" << "WIN40/ADOBEPS4.DRV"; 00429 m_actions << "put" << m_datadir+"/drivers/ADOBEPS4.HLP" << "WIN40/ADOBEPS4.HLP"; 00430 m_actions << "put" << m_datadir+"/drivers/DEFPRTR2.PPD" << "WIN40/DEFPRTR2.PPD"; 00431 m_actions << "put" << m_datadir+"/drivers/ICONLIB.DLL" << "WIN40/ICONLIB.DLL"; 00432 m_actions << "put" << m_datadir+"/drivers/PSMON.DLL" << "WIN40/PSMON.DLL"; 00433 m_actions << "quit"; 00434 00435 m_proc.clearArguments(); 00436 m_proc << "smbclient" << QString::fromLatin1("//")+m_servered->text()+"/print$"; 00437 return startProcess(); 00438 } 00439 00440 bool CupsAddSmb::doInstall() 00441 { 00442 m_status = false; 00443 m_state = None; 00444 00445 m_actions.clear(); 00446 m_actions << "adddriver" << "Windows NT x86" << m_dest+":ADOBEPS5.DLL:"+m_dest+".PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL"; 00447 // seems to be wrong with newer versions of Samba 00448 //m_actions << "addprinter" << m_dest; 00449 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"; 00450 // seems to be ok with newer versions of Samba 00451 m_actions << "setdriver" << m_dest; 00452 m_actions << "quit"; 00453 00454 //m_text->setText(i18n("Preparing to install driver on host <b>%1</b>").arg(m_servered->text())); 00455 m_textinfo->setText(i18n("Preparing to install driver on host %1").arg(m_servered->text())); 00456 00457 m_proc.clearArguments(); 00458 m_proc << "rpcclient" << m_servered->text(); 00459 return startProcess(); 00460 } 00461 00462 bool CupsAddSmb::startProcess() 00463 { 00464 m_proc << "-d" << "0" << "-N" << "-U"; 00465 if (m_passwded->text().isEmpty()) 00466 m_proc << m_logined->text(); 00467 else 00468 m_proc << m_logined->text()+"%"+m_passwded->text(); 00469 m_state = Start; 00470 m_actionindex = 0; 00471 m_buffer.clear(); 00472 kdDebug(500) << "PROCESS STARTED = " << m_proc.args()[0] << endl; 00473 return m_proc.start(KProcess::NotifyOnExit, KProcess::All); 00474 } 00475 00476 #include "cupsaddsmb2.moc"
KDE Logo
This file is part of the documentation for kdeprint Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:23:16 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003