smbview.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 "smbview.h" 00021 00022 #include <kprocess.h> 00023 #include <tdetempfile.h> 00024 #include <tqheader.h> 00025 #include <tqapplication.h> 00026 00027 #include <kiconloader.h> 00028 #include <tdelocale.h> 00029 #include <kdebug.h> 00030 #include <tdemessagebox.h> 00031 #include <kcursor.h> 00032 00033 #include <tqfile.h> 00034 #include <tqtextstream.h> 00035 #include <cstdlib> 00036 00037 00038 //********************************************************************************************* 00039 00040 SmbView::SmbView(TQWidget *parent, const char *name) 00041 : TDEListView(parent,name) 00042 { 00043 addColumn(i18n("Printer")); 00044 addColumn(i18n("Comment")); 00045 setFrameStyle(TQFrame::WinPanel|TQFrame::Sunken); 00046 setLineWidth(1); 00047 setAllColumnsShowFocus(true); 00048 setRootIsDecorated(true); 00049 00050 m_state = Idle; 00051 m_current = 0; 00052 m_proc = new TDEProcess(); 00053 m_proc->setUseShell(true); 00054 m_passwdFile = 0; 00055 connect(m_proc,TQT_SIGNAL(processExited(TDEProcess*)),TQT_SLOT(slotProcessExited(TDEProcess*))); 00056 connect(m_proc,TQT_SIGNAL(receivedStdout(TDEProcess*,char*,int)),TQT_SLOT(slotReceivedStdout(TDEProcess*,char*,int))); 00057 connect(this,TQT_SIGNAL(selectionChanged(TQListViewItem*)),TQT_SLOT(slotSelectionChanged(TQListViewItem*))); 00058 } 00059 00060 SmbView::~SmbView() 00061 { 00062 delete m_proc; 00063 delete m_passwdFile; 00064 } 00065 00066 void SmbView::setLoginInfos(const TQString& login, const TQString& password) 00067 { 00068 m_login = login; 00069 m_password = password; 00070 00071 // We can't pass the password via the command line or the environment 00072 // because the command line is publically accessible on most OSes and 00073 // the environment is publically accessible on some OSes. 00074 // Therefor we write the password to a file and pass that file to 00075 // smbclient with the -A option 00076 delete m_passwdFile; 00077 m_passwdFile = new KTempFile; 00078 m_passwdFile->setAutoDelete(true); 00079 00080 TQTextStream *passwdFile = m_passwdFile->textStream(); 00081 if (!passwdFile) return; // Error 00082 (*passwdFile) << "username = " << m_login << endl; 00083 (*passwdFile) << "password = " << m_password << endl; 00084 // (*passwdFile) << "domain = " << ???? << endl; 00085 00086 m_passwdFile->close(); 00087 } 00088 00089 void SmbView::startProcess(int state) 00090 { 00091 m_buffer = TQString::null; 00092 m_state = state; 00093 TQApplication::setOverrideCursor(KCursor::waitCursor()); 00094 m_proc->start(TDEProcess::NotifyOnExit,TDEProcess::Stdout); 00095 emit running(true); 00096 } 00097 00098 void SmbView::endProcess() 00099 { 00100 switch (m_state) 00101 { 00102 case GroupListing: 00103 processGroups(); 00104 break; 00105 case ServerListing: 00106 processServers(); 00107 break; 00108 case ShareListing: 00109 processShares(); 00110 break; 00111 default: 00112 break; 00113 } 00114 m_state = Idle; 00115 TQApplication::restoreOverrideCursor(); 00116 emit running(false); 00117 // clean up for future usage 00118 m_proc->clearArguments(); 00119 } 00120 00121 void SmbView::slotProcessExited(TDEProcess*) 00122 { 00123 endProcess(); 00124 } 00125 00126 void SmbView::slotReceivedStdout(TDEProcess*, char *buf, int len) 00127 { 00128 m_buffer.append(TQString::fromLocal8Bit(buf,len)); 00129 } 00130 00131 void SmbView::init() 00132 { 00133 // Open Samba configuration file and check if a WINS server is defined 00134 m_wins_server = TQString::null; 00135 TQString wins_keyword("wins server"); 00136 TQFile smb_conf ("/etc/samba/smb.conf"); 00137 if (smb_conf.exists () && smb_conf.open (IO_ReadOnly)) 00138 { 00139 TQTextStream smb_stream (&smb_conf); 00140 while (!smb_stream.atEnd ()) 00141 { 00142 TQString smb_line = smb_stream.readLine (); 00143 if (smb_line.contains (wins_keyword, FALSE) > 0) 00144 { 00145 TQString key = smb_line.section ('=', 0, 0); 00146 key = key.stripWhiteSpace(); 00147 if (key.lower() == wins_keyword) 00148 { 00149 continue; 00150 } 00151 m_wins_server = smb_line.section ('=', 1, 1); 00152 // take only the first declared WINS server 00153 m_wins_server = m_wins_server.section(',', 0, 0); 00154 m_wins_server = m_wins_server.stripWhiteSpace (); 00155 m_wins_server = m_wins_server.section(' ', 0, 0); 00156 // strip any server tag (see man smb.conf(5)) 00157 if (m_wins_server.section(':', 1, 1) != NULL) 00158 { 00159 m_wins_server = m_wins_server.section(':', 1, 1); 00160 } 00161 break; 00162 } 00163 } 00164 smb_conf.close (); 00165 } 00166 m_wins_server = m_wins_server.isEmpty ()? " " : " -U " + m_wins_server + " "; 00167 TQString cmd ("nmblookup" + m_wins_server + 00168 "-M -- - | grep '<01>' | awk '{print $1}' | xargs nmblookup -A | grep '<1d>'"); 00169 *m_proc << cmd; 00170 startProcess(GroupListing); 00171 } 00172 00173 void SmbView::setOpen(TQListViewItem *item, bool on) 00174 { 00175 if (on && item->childCount() == 0) 00176 { 00177 if (item->depth() == 0) 00178 { // opening group 00179 m_current = item; 00180 *m_proc << "nmblookup"+m_wins_server+"-M "; 00181 *m_proc << TDEProcess::quote(item->text(0)); 00182 *m_proc << " -S"; 00183 startProcess(ServerListing); 00184 } 00185 else if (item->depth() == 1) 00186 { // opening server 00187 char *krb5ccname = getenv ("KRB5CCNAME"); 00188 m_current = item; 00189 if (krb5ccname) 00190 { 00191 *m_proc << "smbclient -k -N -L "; 00192 } 00193 else 00194 { 00195 *m_proc << "smbclient -N -L "; 00196 } 00197 *m_proc << TDEProcess::quote (item->text (0)); 00198 *m_proc << " -W "; 00199 *m_proc << TDEProcess::quote (item->parent ()-> 00200 text (0)); 00201 if (!krb5ccname) 00202 { 00203 *m_proc << " -A "; 00204 *m_proc << TDEProcess:: 00205 quote (m_passwdFile->name ()); 00206 } 00207 startProcess(ShareListing); 00208 } 00209 } 00210 TQListView::setOpen(item,on); 00211 } 00212 00213 void SmbView::processGroups() 00214 { 00215 TQStringList grps = TQStringList::split('\n',m_buffer,false); 00216 clear(); 00217 for (TQStringList::ConstIterator it=grps.begin(); it!=grps.end(); ++it) 00218 { 00219 int p = (*it).find("<1d>"); 00220 if (p == -1) 00221 continue; 00222 TQListViewItem *item = new TQListViewItem(this,(*it).left(p).stripWhiteSpace()); 00223 item->setExpandable(true); 00224 item->setPixmap(0,SmallIcon("network")); 00225 } 00226 } 00227 00228 void SmbView::processServers() 00229 { 00230 TQStringList lines = TQStringList::split('\n',m_buffer,true); 00231 TQString line; 00232 uint index(0); 00233 while (index < lines.count()) 00234 { 00235 line = lines[index++].stripWhiteSpace(); 00236 if (line.isEmpty()) 00237 break; 00238 TQStringList words = TQStringList::split(' ',line,false); 00239 if (words[1] != "<00>" || words[3] == "<GROUP>") 00240 continue; 00241 TQListViewItem *item = new TQListViewItem(m_current,words[0]); 00242 item->setExpandable(true); 00243 item->setPixmap(0,SmallIcon("tdeprint_computer")); 00244 } 00245 } 00246 00247 void SmbView::processShares() 00248 { 00249 TQStringList lines = TQStringList::split('\n',m_buffer,true); 00250 TQString line; 00251 uint index(0); 00252 for (;index < lines.count();index++) 00253 if (lines[index].stripWhiteSpace().startsWith("Sharename")) 00254 break; 00255 index += 2; 00256 while (index < lines.count()) 00257 { 00258 line = lines[index++].stripWhiteSpace(); 00259 if (line.isEmpty()) 00260 break; 00261 else if ( line.startsWith( "Error returning" ) ) 00262 { 00263 KMessageBox::error( this, line ); 00264 break; 00265 } 00266 TQString typestr(line.mid(15, 10).stripWhiteSpace()); 00267 //TQStringList words = TQStringList::split(' ',line,false); 00268 //if (words[1] == "Printer") 00269 if (typestr == "Printer") 00270 { 00271 TQString comm(line.mid(25).stripWhiteSpace()), sharen(line.mid(0, 15).stripWhiteSpace()); 00272 //for (uint i=2; i<words.count(); i++) 00273 // comm += (words[i]+" "); 00274 //TQListViewItem *item = new TQListViewItem(m_current,words[0],comm); 00275 TQListViewItem *item = new TQListViewItem(m_current,sharen,comm); 00276 item->setPixmap(0,SmallIcon("tdeprint_printer")); 00277 } 00278 } 00279 } 00280 00281 void SmbView::slotSelectionChanged(TQListViewItem *item) 00282 { 00283 if (item && item->depth() == 2) 00284 emit printerSelected(item->parent()->parent()->text(0),item->parent()->text(0),item->text(0)); 00285 } 00286 00287 void SmbView::abort() 00288 { 00289 if (m_proc->isRunning()) 00290 m_proc->kill(); 00291 } 00292 #include "smbview.moc"