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

tdeprint

cupsaddsmb2.cpp

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