diff options
Diffstat (limited to 'tdeioslave')
181 files changed, 3446 insertions, 9072 deletions
diff --git a/tdeioslave/CMakeLists.txt b/tdeioslave/CMakeLists.txt index 56b05c852..5b0f0c155 100644 --- a/tdeioslave/CMakeLists.txt +++ b/tdeioslave/CMakeLists.txt @@ -23,7 +23,6 @@ add_subdirectory( nfs ) add_subdirectory( nntp ) add_subdirectory( pop3 ) add_subdirectory( smtp ) -add_subdirectory( sftp ) add_subdirectory( tar ) add_subdirectory( finger ) add_subdirectory( thumbnail ) @@ -35,3 +34,4 @@ add_subdirectory( home ) add_subdirectory( system ) tde_conditional_add_subdirectory( WITH_LDAP ldap ) tde_conditional_add_subdirectory( WITH_SAMBA smb ) +tde_conditional_add_subdirectory( WITH_SFTP sftp ) diff --git a/tdeioslave/cgi/kcmcgi/kcmcgi.cpp b/tdeioslave/cgi/kcmcgi/kcmcgi.cpp index a4297969e..456c9d45f 100644 --- a/tdeioslave/cgi/kcmcgi/kcmcgi.cpp +++ b/tdeioslave/cgi/kcmcgi/kcmcgi.cpp @@ -48,7 +48,7 @@ KCMCgi::KCMCgi(TQWidget *parent, const char *name) TQVBoxLayout *topLayout = new TQVBoxLayout(this, 0, KDialog::spacingHint()); - TQGroupBox *topBox = new TQGroupBox( 1, Qt::Horizontal, i18n("Paths to Local CGI Programs"), this ); + TQGroupBox *topBox = new TQGroupBox( 1, TQt::Horizontal, i18n("Paths to Local CGI Programs"), this ); topLayout->addWidget( topBox ); mListBox = new TQListBox( topBox ); @@ -57,11 +57,11 @@ KCMCgi::KCMCgi(TQWidget *parent, const char *name) buttonBox->setSpacing( KDialog::spacingHint() ); mAddButton = new TQPushButton( i18n("Add..."), buttonBox ); - connect( mAddButton, TQT_SIGNAL( clicked() ), TQT_SLOT( addPath() ) ); + connect( mAddButton, TQ_SIGNAL( clicked() ), TQ_SLOT( addPath() ) ); mRemoveButton = new TQPushButton( i18n("Remove"), buttonBox ); - connect( mRemoveButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removePath() ) ); - connect( mListBox, TQT_SIGNAL( clicked ( TQListBoxItem * )),this, TQT_SLOT( slotItemSelected( TQListBoxItem *))); + connect( mRemoveButton, TQ_SIGNAL( clicked() ), TQ_SLOT( removePath() ) ); + connect( mListBox, TQ_SIGNAL( clicked ( TQListBoxItem * )),this, TQ_SLOT( slotItemSelected( TQListBoxItem *))); mConfig = new TDEConfig("kcmcgirc"); diff --git a/tdeioslave/cgi/kcmcgi/kcmcgi.h b/tdeioslave/cgi/kcmcgi/kcmcgi.h index ccd2f2f3d..0522fa24a 100644 --- a/tdeioslave/cgi/kcmcgi/kcmcgi.h +++ b/tdeioslave/cgi/kcmcgi/kcmcgi.h @@ -27,7 +27,7 @@ class TDEConfig; class KCMCgi : public TDECModule { - Q_OBJECT + TQ_OBJECT public: KCMCgi( TQWidget *parent = 0, const char *name = 0 ); ~KCMCgi(); diff --git a/tdeioslave/filter/CMakeLists.txt b/tdeioslave/filter/CMakeLists.txt index 446393d74..4387ab0f5 100644 --- a/tdeioslave/filter/CMakeLists.txt +++ b/tdeioslave/filter/CMakeLists.txt @@ -34,7 +34,7 @@ tde_create_translated_desktop( set( target tdeio_filter ) tde_add_kpart( ${target} AUTOMOC - SOURCES filter.cc + SOURCES filter.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/filter/Makefile.am b/tdeioslave/filter/Makefile.am index fcf2a9e9f..10a83993d 100644 --- a/tdeioslave/filter/Makefile.am +++ b/tdeioslave/filter/Makefile.am @@ -4,7 +4,7 @@ INCLUDES = $(all_includes) kde_module_LTLIBRARIES = tdeio_filter.la -tdeio_filter_la_SOURCES = filter.cc +tdeio_filter_la_SOURCES = filter.cpp tdeio_filter_la_LIBADD = $(LIB_TDESYCOCA) tdeio_filter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = filter.h diff --git a/tdeioslave/filter/filter.cc b/tdeioslave/filter/filter.cpp index a429103e1..a429103e1 100644 --- a/tdeioslave/filter/filter.cc +++ b/tdeioslave/filter/filter.cpp diff --git a/tdeioslave/finger/tdeio_finger.cpp b/tdeioslave/finger/tdeio_finger.cpp index 643a699f0..621d33301 100644 --- a/tdeioslave/finger/tdeio_finger.cpp +++ b/tdeioslave/finger/tdeio_finger.cpp @@ -126,10 +126,10 @@ void FingerProtocol::get(const KURL& url ) << *myFingerPath << *myFingerCSSFile << refreshRate << myURL->host() << myURL->user() ; - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - //connect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), - // this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + connect(myTDEProcess, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + //connect(myTDEProcess, TQ_SIGNAL(receivedStderr(TDEProcess *, char *, int)), + // this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); myTDEProcess->start(TDEProcess::Block, TDEProcess::All); diff --git a/tdeioslave/finger/tdeio_finger.h b/tdeioslave/finger/tdeio_finger.h index 3d083d2ed..079c82305 100644 --- a/tdeioslave/finger/tdeio_finger.h +++ b/tdeioslave/finger/tdeio_finger.h @@ -30,7 +30,7 @@ class FingerProtocol : public TQObject, public TDEIO::SlaveBase { - Q_OBJECT + TQ_OBJECT public: @@ -46,12 +46,12 @@ private slots: private: KURL *myURL; - QString *myPerlPath; + TQString *myPerlPath; TQString *myFingerPath; TQString *myFingerPerlScript; TQString *myFingerCSSFile; - QString *myStdStream; + TQString *myStdStream; TDEProcess *myTDEProcess; diff --git a/tdeioslave/fish/fish.cpp b/tdeioslave/fish/fish.cpp index 98c11a712..6f6cd93c6 100644 --- a/tdeioslave/fish/fish.cpp +++ b/tdeioslave/fish/fish.cpp @@ -570,7 +570,9 @@ int fishProtocol::establishConnection(char *buffer, TDEIO::fileoffset_t len) { infoMessage(i18n("Initiating protocol...")); if (!connectionAuth.password.isEmpty()) { connectionAuth.password = connectionAuth.password.left(connectionAuth.password.length()-1); - cacheAuthentication(connectionAuth); + if (connectionAuth.keepPassword) { + cacheAuthentication(connectionAuth); + } } isLoggedIn = true; return 0; @@ -774,7 +776,7 @@ int fishProtocol::handleResponse(const TQString &str){ int fishProtocol::makeTimeFromLs(const TQString &monthStr, const TQString &dayStr, const TQString &timeyearStr) { - TQDateTime dt(TQDate::currentDate(Qt::UTC)); + TQDateTime dt(TQDate::currentDate(TQt::UTC)); int year = dt.date().year(); int month = dt.date().month(); int currentMonth = month; diff --git a/tdeioslave/floppy/tdeio_floppy.cpp b/tdeioslave/floppy/tdeio_floppy.cpp index c67af0b39..50303f1b7 100644 --- a/tdeioslave/floppy/tdeio_floppy.cpp +++ b/tdeioslave/floppy/tdeio_floppy.cpp @@ -1105,7 +1105,7 @@ void FloppyProtocol::put( const KURL& url, int , bool overwrite, bool ) int bytesRead(0); TQByteArray array; - //from file.cc + //from file.cpp // Loop until we got 0 (end of data) do { diff --git a/tdeioslave/home/Makefile.am b/tdeioslave/home/Makefile.am index 3bd078852..4176a196a 100644 --- a/tdeioslave/home/Makefile.am +++ b/tdeioslave/home/Makefile.am @@ -28,5 +28,5 @@ check: testhome ./testhome messages: - $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_home.pot + $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_home.pot diff --git a/tdeioslave/home/homeimpl.cpp b/tdeioslave/home/homeimpl.cpp index ea3dad520..8967e5ea4 100644 --- a/tdeioslave/home/homeimpl.cpp +++ b/tdeioslave/home/homeimpl.cpp @@ -193,8 +193,8 @@ TDEIO::UDSEntry HomeImpl::extractUrlInfos(const KURL &url) m_entryBuffer.clear(); TDEIO::StatJob *job = TDEIO::stat(url, false); - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( slotStatResult(TDEIO::Job *) ) ); + connect( job, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( slotStatResult(TDEIO::Job *) ) ); tqApp->eventLoop()->enterLoop(); TDEIO::UDSEntry::iterator it = m_entryBuffer.begin(); diff --git a/tdeioslave/home/homeimpl.h b/tdeioslave/home/homeimpl.h index 5884d8ab7..abc106bcb 100644 --- a/tdeioslave/home/homeimpl.h +++ b/tdeioslave/home/homeimpl.h @@ -27,9 +27,9 @@ #include <tqstring.h> -class HomeImpl : public QObject +class HomeImpl : public TQObject { -Q_OBJECT +TQ_OBJECT public: HomeImpl(); diff --git a/tdeioslave/info/CMakeLists.txt b/tdeioslave/info/CMakeLists.txt index 6f243ba3f..85937d486 100644 --- a/tdeioslave/info/CMakeLists.txt +++ b/tdeioslave/info/CMakeLists.txt @@ -37,7 +37,7 @@ install( PROGRAMS kde-info2html DESTINATION ${DATA_INSTALL_DIR}/tdeio_info ) set( target tdeio_info ) tde_add_kpart( ${target} AUTOMOC - SOURCES info.cc + SOURCES info.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/info/Makefile.am b/tdeioslave/info/Makefile.am index a682f4a77..8f0541c0f 100644 --- a/tdeioslave/info/Makefile.am +++ b/tdeioslave/info/Makefile.am @@ -8,7 +8,7 @@ METASOURCES = AUTO kde_module_LTLIBRARIES = tdeio_info.la -tdeio_info_la_SOURCES = info.cc +tdeio_info_la_SOURCES = info.cpp tdeio_info_la_LIBADD = $(LIB_TDEIO) tdeio_info_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = info.h diff --git a/tdeioslave/info/info.cc b/tdeioslave/info/info.cpp index 83b41dae8..83b41dae8 100644 --- a/tdeioslave/info/info.cc +++ b/tdeioslave/info/info.cpp diff --git a/tdeioslave/mac/TODO b/tdeioslave/mac/TODO index 69fcb0d2e..469a616be 100644 --- a/tdeioslave/mac/TODO +++ b/tdeioslave/mac/TODO @@ -5,7 +5,7 @@ grep TODO tdeio_mac.cpp //TODO this means dev=foo must be the last argument in the query //TODO this error interrupts the user when typing ?dev=foo on each letter of foo //TODO are there any more characters to escape? - QString theSize(fileRE.group(4)); //TODO: this is data size, what about resource size? + TQString theSize(fileRE.group(4)); //TODO: this is data size, what about resource size? Future things: - maybe make it work with plain old hfs partitions diff --git a/tdeioslave/mac/tdeio_mac.cpp b/tdeioslave/mac/tdeio_mac.cpp index caef50784..d116ef909 100644 --- a/tdeioslave/mac/tdeio_mac.cpp +++ b/tdeioslave/mac/tdeio_mac.cpp @@ -105,8 +105,8 @@ void MacProtocol::get(const KURL& url) { *myTDEProcess << "hpcopy" << mode << path << "-"; //data is now sent directly from the slot - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotSetDataStdOutput(TDEProcess *, char *, int))); + connect(myTDEProcess, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQ_SLOT(slotSetDataStdOutput(TDEProcess *, char *, int))); myTDEProcess->start(TDEProcess::Block, TDEProcess::All); @@ -134,8 +134,8 @@ void MacProtocol::listDir(const KURL& url) { *myTDEProcess << "hpls" << "-la" << filename; standardOutputStream = TQString::null; - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + connect(myTDEProcess, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); myTDEProcess->start(TDEProcess::Block, TDEProcess::All); @@ -146,8 +146,8 @@ void MacProtocol::listDir(const KURL& url) { //clean up delete myTDEProcess; myTDEProcess = 0; - disconnect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + disconnect(myTDEProcess, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); UDSEntry entry; if (!standardOutputStream.isEmpty()) { @@ -191,8 +191,8 @@ TQValueList<TDEIO::UDSAtom> MacProtocol::doStat(const KURL& url) { *myTDEProcess << "hpls" << "-ld" << filename; standardOutputStream = TQString::null; - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + connect(myTDEProcess, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); myTDEProcess->start(TDEProcess::Block, TDEProcess::All); @@ -203,8 +203,8 @@ TQValueList<TDEIO::UDSAtom> MacProtocol::doStat(const KURL& url) { //clean up delete myTDEProcess; myTDEProcess = 0; - disconnect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + disconnect(myTDEProcess, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); if (standardOutputStream.isEmpty()) { filename.replace("\\ ", " "); //get rid of escapes @@ -257,8 +257,8 @@ TQString MacProtocol::prepareHP(const KURL& url) { myTDEProcess = new TDEProcess(); *myTDEProcess << "hpmount"; standardOutputStream = TQString::null; - connect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + connect(myTDEProcess, TQ_SIGNAL(receivedStderr(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); myTDEProcess->start(TDEProcess::Block, TDEProcess::All); @@ -269,8 +269,8 @@ TQString MacProtocol::prepareHP(const KURL& url) { } delete myTDEProcess; myTDEProcess = 0; - disconnect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + disconnect(myTDEProcess, TQ_SIGNAL(receivedStderr(TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); //now mount the drive myTDEProcess = new TDEProcess(); diff --git a/tdeioslave/mac/tdeio_mac.h b/tdeioslave/mac/tdeio_mac.h index e497e9918..ca4f8b95a 100644 --- a/tdeioslave/mac/tdeio_mac.h +++ b/tdeioslave/mac/tdeio_mac.h @@ -28,7 +28,7 @@ class MacProtocol : public TQObject, public TDEIO::SlaveBase { - Q_OBJECT + TQ_OBJECT public: MacProtocol(const TQCString &pool, const TQCString &app); ~MacProtocol(); diff --git a/tdeioslave/man/kmanpart.cpp b/tdeioslave/man/kmanpart.cpp index 556b287e4..703ec2202 100644 --- a/tdeioslave/man/kmanpart.cpp +++ b/tdeioslave/man/kmanpart.cpp @@ -95,8 +95,8 @@ bool KManPart::openFile() url.setPath( m_file ); m_job = TDEIO::get( url, true, false ); - connect( m_job, TQT_SIGNAL( data( TDEIO::Job *, const TQByteArray &) ), TQT_SLOT( readData( TDEIO::Job *, const TQByteArray &) ) ); - connect( m_job, TQT_SIGNAL( result( TDEIO::Job * ) ), TQT_SLOT( jobDone( TDEIO::Job * ) ) ); + connect( m_job, TQ_SIGNAL( data( TDEIO::Job *, const TQByteArray &) ), TQ_SLOT( readData( TDEIO::Job *, const TQByteArray &) ) ); + connect( m_job, TQ_SIGNAL( result( TDEIO::Job * ) ), TQ_SLOT( jobDone( TDEIO::Job * ) ) ); return true; } diff --git a/tdeioslave/man/kmanpart.h b/tdeioslave/man/kmanpart.h index 908cca538..4fdb45733 100644 --- a/tdeioslave/man/kmanpart.h +++ b/tdeioslave/man/kmanpart.h @@ -39,7 +39,7 @@ class TDEAboutData; */ class KManPartFactory: public KParts::Factory { - Q_OBJECT + TQ_OBJECT public: KManPartFactory( TQObject * parent = 0, const char * name = 0 ); virtual ~KManPartFactory(); @@ -58,7 +58,7 @@ class KManPartFactory: public KParts::Factory class KManPart : public TDEHTMLPart { - Q_OBJECT + TQ_OBJECT public: KManPart( TQWidget * parent, const char * name = 0L ); KParts::BrowserExtension * extension() {return m_extension;} diff --git a/tdeioslave/man/man2html.cpp b/tdeioslave/man/man2html.cpp index 8dd23dc6a..3f27feb68 100644 --- a/tdeioslave/man/man2html.cpp +++ b/tdeioslave/man/man2html.cpp @@ -18,8 +18,6 @@ // End of verbatim comment -// kate: space-indent on; indent-width 4; replace-tabs on; - /* * man2html-linux-1.0/1.1 * This version modified for Redhat/Caldera linux - March 1996. @@ -332,7 +330,7 @@ static void InitNumberDefinitions( void ) { // As the date number registers are more for end-users, better choose local time. // Groff seems to support Gregorian dates only - TQDate today( TQDate::currentDate( Qt::LocalTime ) ); + TQDate today( TQDate::currentDate( TQt::LocalTime ) ); s_numberDefinitionMap.insert( "year", today.year() ); // Y2K-correct year s_numberDefinitionMap.insert( "yr", today.year() - 1900 ); // Y2K-incorrect year s_numberDefinitionMap.insert( "mo", today.month() ); @@ -4192,13 +4190,13 @@ static char *scan_request(char *c) if (mode) { // .rm ReMove - s_stringDefinitionMap.remove(name); // ### QT4: removeAll + s_stringDefinitionMap.remove(name); } else { // .rn ReName StringDefinition def=(*it); - s_stringDefinitionMap.remove(name); // ### QT4: removeAll + s_stringDefinitionMap.remove(name); s_stringDefinitionMap.insert(name2,def); } } @@ -5154,7 +5152,7 @@ static char *scan_request(char *c) else { NumberDefinition def=(*it); - s_numberDefinitionMap.remove(name); // ### QT4: removeAll + s_numberDefinitionMap.remove(name); s_numberDefinitionMap.insert(name2,def); } kdDebug(7107) << "end .rnn" << endl; diff --git a/tdeioslave/man/tdeio_man.cpp b/tdeioslave/man/tdeio_man.cpp index 92530facb..cd04f702e 100644 --- a/tdeioslave/man/tdeio_man.cpp +++ b/tdeioslave/man/tdeio_man.cpp @@ -204,8 +204,8 @@ TQMap<TQString, TQString> MANProtocol::buildIndexMap(const TQString §ion) TDEProcess proc; proc << "whatis" << "-M" << (*it_dir) << "-w" << "*"; myStdStream = TQString::null; - connect( &proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int ) ), - TQT_SLOT( slotGetStdOutput( TDEProcess *, char *, int ) ) ); + connect( &proc, TQ_SIGNAL( receivedStdout(TDEProcess *, char *, int ) ), + TQ_SLOT( slotGetStdOutput( TDEProcess *, char *, int ) ) ); proc.start( TDEProcess::Block, TDEProcess::Stdout ); TQTextStream t( &myStdStream, IO_ReadOnly ); parseWhatIs( i, t, mark ); @@ -555,8 +555,8 @@ char *MANProtocol::readManPage(const char *_filename) getProgramPath(); proc << mySgml2RoffPath << filename; - TQApplication::connect(&proc, TQT_SIGNAL(receivedStdout (TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + TQApplication::connect(&proc, TQ_SIGNAL(receivedStdout (TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); proc.start(TDEProcess::Block, TDEProcess::All); const TQCString cstr=myStdStream.latin1(); @@ -589,8 +589,8 @@ char *MANProtocol::readManPage(const char *_filename) proc << "man" << "--recode" << "UTF-8" << filename; - TQApplication::connect(&proc, TQT_SIGNAL(receivedStdout (TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutputUtf8(TDEProcess *, char *, int))); + TQApplication::connect(&proc, TQ_SIGNAL(receivedStdout (TDEProcess *, char *, int)), + this, TQ_SLOT(slotGetStdOutputUtf8(TDEProcess *, char *, int))); proc.start(TDEProcess::Block, TDEProcess::All); const TQCString cstr=myStdStream.utf8(); @@ -963,6 +963,7 @@ void MANProtocol::constructPath(TQStringList& constr_path, TQStringList constr_c "/usr/sunpc/man", "/usr/ncd/man", "/usr/newsprint/man", + TDE_MANDIR, NULL }; diff --git a/tdeioslave/man/tdeio_man.h b/tdeioslave/man/tdeio_man.h index e621a7fbf..89c1d29c4 100644 --- a/tdeioslave/man/tdeio_man.h +++ b/tdeioslave/man/tdeio_man.h @@ -34,7 +34,7 @@ class MANProtocol : public TQObject, public TDEIO::SlaveBase { - Q_OBJECT + TQ_OBJECT public: diff --git a/tdeioslave/man/tdeio_man_test.cpp b/tdeioslave/man/tdeio_man_test.cpp index 131e03541..898a18eaa 100644 --- a/tdeioslave/man/tdeio_man_test.cpp +++ b/tdeioslave/man/tdeio_man_test.cpp @@ -11,7 +11,7 @@ class tdeio_man_test : public MANProtocol { - Q_OBJECT + TQ_OBJECT public: tdeio_man_test(const TQCString &pool_socket, const TQCString &app_socket); diff --git a/tdeioslave/media/Makefile.am b/tdeioslave/media/Makefile.am index a5551fb2e..2ce7900b4 100644 --- a/tdeioslave/media/Makefile.am +++ b/tdeioslave/media/Makefile.am @@ -1,7 +1,3 @@ -if include_media_halbackend -PROPSDLGPLUGINDIR = propsdlgplugin -endif - SUBDIRS = libmediacommon . mediamanager medianotifier mounthelper \ tdefile-plugin tdecmodule mimetypes services $(PROPSDLGPLUGINDIR) diff --git a/tdeioslave/media/configure.in.in b/tdeioslave/media/configure.in.in index 413848b64..a6718eb16 100644 --- a/tdeioslave/media/configure.in.in +++ b/tdeioslave/media/configure.in.in @@ -6,179 +6,3 @@ AC_CHECK_HEADER(linux/cdrom.h, LINUXCDPOLLING=yes AC_SUBST(LINUXCDPOLLING) ]) - - -AC_ARG_WITH(hal,AC_HELP_STRING([--with-hal],[Enable HAL support [default=check]]),[hal_test="$withval"],[hal_test="yes"]) - -if test "x$hal_test" = "xyes" ; then - -########### Check for the HAL - AC_MSG_CHECKING(for the HAL) - - hal_inc=NOTFOUND - hal_lib=NOTFOUND - hal=NOTFOUND - - search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/hal /usr/local/include /usr/local/include/hal" - AC_FIND_FILE(libhal.h libhal-storage.h, $search_incs, hal_incdir) - - if test -r $hal_incdir/libhal.h && test -r $hal_incdir/libhal-storage.h && grep LibHalVolume $hal_incdir/libhal-storage.h > /dev/null 2>&1; then - HAL_INCS="-I$hal_incdir" - hal_inc=FOUND - fi - - search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" - AC_FIND_FILE(libhal.so libhal-storage.so, $search_libs, hal_libdir) - - if test -r $hal_libdir/libhal.so && test -r $hal_libdir/libhal-storage.so ; then - HAL_LIBS="-L$hal_libdir -lhal -lhal-storage" - hal_lib=FOUND - fi - - if test "$hal_inc" != FOUND || test "$hal_lib" != FOUND; then - KDE_PKG_CHECK_MODULES( HAL, hal > 0.5, [ HAL_INCS=$HAL_CFLAGS; hal_inc=FOUND; hal_lib=FOUND; ] , AC_MSG_RESULT(Nothing found on PKG_CONFIG_PATH) ) - fi - - if test "$hal_inc" = FOUND && test "$hal_lib" = FOUND ; then - AC_MSG_RESULT(headers $HAL_INCS libraries $HAL_LIBS) - hal=FOUND - else - AC_MSG_RESULT(searched but not found) - fi - - - AC_SUBST(HAL_INCS) - AC_SUBST(HAL_LIBS) - - -########### Check for DBus - - AC_MSG_CHECKING(for DBus) - - dbus_inc=NOTFOUND - dbus_lib=NOTFOUND - dbus=NOTFOUND - - search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" - AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) - - search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$tdelibsuff/dbus-1.0/include /usr/local/lib$tdelibsuff/dbus-1.0/include" - AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) - - if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then - DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" - dbus_inc=FOUND - fi - - search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" - AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) - - if test -r $dbus_libdir/libdbus-1.so ; then - DBUS_LIBS="-L$dbus_libdir -ldbus-1" - dbus_lib=FOUND - fi - - if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then - KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) - fi - - dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` - if test -z "$dbus_bus_var"; then - dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" - fi - AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) - - if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then - AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) - dbus=FOUND - else - AC_MSG_RESULT(searched but not found) - fi - - AC_SUBST(DBUS_INCS) - AC_SUBST(DBUS_LIBS) - -########### Check for DBus-Qt3 bindings - - AC_MSG_CHECKING(for DBus-Qt3 bindings) - - dbusqt_inc=NOTFOUND - dbusqt_lib=NOTFOUND - dbusqt=NOTFOUND - - search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" - AC_FIND_FILE(dbus/connection.h, $search_incs, dbusqt_incdir) - - if test -r $dbusqt_incdir/dbus/connection.h ; then - have_qt_patch=0 - grep dbus_connection_setup_with_qt_main $dbusqt_incdir/dbus/connection.h \ - > /dev/null 2>&1 && have_qt_patch=1 - if test $have_qt_patch = 1 ; then - DBUSTQT_INCS="-I$dbusqt_incdir" - dbusqt_inc=FOUND - fi - fi - - search_libs="$kde_libraries $kde_extra_libs /usr/lib$tdelibsuff /usr/local/lib$tdelibsuff" - AC_FIND_FILE(libdbus-qt-1.so, $search_libs, dbusqt_libdir) - - if test -r $dbusqt_libdir/libdbus-qt-1.so ; then - DBUSTQT_LIBS="-L$dbusqt_libdir -ldbus-qt-1" - dbusqt_lib=FOUND - fi - - if test $dbusqt_inc != FOUND || test $dbusqt_lib != FOUND ; then - - search_incs="`pkg-config --cflags dbus-1 |sed 's/-I//g'`" - AC_FIND_FILE(dbus/connection.h, $search_incs, dbusqt_incdir) - if test -r $dbusqt_incdir/dbus/connection.h ; then - have_qt_patch=0 - grep dbus_connection_setup_with_qt_main $dbusqt_incdir/dbus/connection.h \ - > /dev/null 2>&1 && have_qt_patch=1 - if test $have_qt_patch = 1 ; then - DBUSTQT_INCS="-I$dbusqt_incdir" - dbusqt_inc=FOUND - fi - fi - - search_libs="`pkg-config --libs dbus-1 --libs-only-L | sed 's/-L//g'`" - AC_FIND_FILE(libdbus-qt-1.so, $search_libs, dbusqt_libdir) - - if test -r $dbusqt_libdir/libdbus-qt-1.so ; then - DBUSTQT_LIBS="-L$dbusqt_libdir -ldbus-qt-1" - dbusqt_lib=FOUND - fi - - fi - - - if test $dbusqt_inc = FOUND && test $dbusqt_lib = FOUND ; then - AC_MSG_RESULT(headers $dbusqt_incdir libraries $dbusqt_libdir) - dbusqt=FOUND - else - AC_MSG_RESULT(searched but not found) - fi - - AC_SUBST(DBUSTQT_INCS) - AC_SUBST(DBUSTQT_LIBS) -fi - -########### Check if media HAL backend sould be compiled - -AC_MSG_CHECKING(if the HAL backend for media:/ should be compiled) - -HALBACKEND=no -if test "x$hal" = "xFOUND" && test "x$dbus" = "xFOUND" && test "x$dbusqt" = "xFOUND" ; then - AC_DEFINE_UNQUOTED([COMPILE_HALBACKEND],1, [media HAL backend compilation]) - HALBACKEND=yes - AC_SUBST(HALBACKEND) - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -AM_CONDITIONAL(include_media_linuxcdpolling, test "$LINUXCDPOLLING" = "yes") -AM_CONDITIONAL(include_media_halbackend, test "$HALBACKEND" = yes) - -AC_CHECK_FUNCS(statvfs) - diff --git a/tdeioslave/media/contrib/README b/tdeioslave/media/contrib/README index 8f6041578..4e330e073 100644 --- a/tdeioslave/media/contrib/README +++ b/tdeioslave/media/contrib/README @@ -1,11 +1,5 @@ Those scripts are an example on how to allow media:/ to use -hotplugging events if you don't use HAL. They're targeting -"Linux 2.6 + hotplug + udev" platforms, but we can surely make -something equivalent for Linux 2.4, FreeBSD... - -They are just examples, the packagers will surely develop their -own version (I'm currently using them on Debian Sid, Linux 2.6.9 -though). +hotplugging events. 1) mediamanager_usbstorage.dev This file only needs to be copied to /etc/dev.d/default diff --git a/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg index 32725c1bb..8136ecd79 100644 --- a/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg +++ b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg @@ -4,11 +4,6 @@ <kcfg> <kcfgfile name="mediamanagerrc"/> <group name="Global"> - <entry name="HalBackendEnabled" type="Bool"> - <label>Enable HAL backend</label> - <whatsthis>When HAL (Hardware Abstraction Layer) support is enabled, TDE will use it to gather information on the storage media available in your system.</whatsthis> - <default>true</default> - </entry> <entry name="TdeHardwareBackendEnabled" type="Bool"> <label>Enable TDE hardware library backend</label> <whatsthis>When TDE hardware library support is enabled, TDE will use it to gather information on the storage media available in your system.</whatsthis> @@ -25,8 +20,13 @@ <default>true</default> </entry> <entry name="NotificationPopupsEnabled" type="Bool"> - <label>Enable notification popups</label> - <whatsthis>Deselect this if you do not want action request popups to be generated when devices are plugged in.</whatsthis> + <label>Enable notification dialogs popups</label> + <whatsthis>Deselect this if you do not want action request dialog popups to be generated when devices are plugged in.</whatsthis> + <default>true</default> + </entry> + <entry name="DeviceMonitorPopupsEnabled" type="Bool"> + <label>Enable device monitor notification popups</label> + <whatsthis>Deselect this if you do not want device monitoring popups to be generated when devices are added, modified or removed.</whatsthis> <default>true</default> </entry> </group> diff --git a/tdeioslave/media/libmediacommon/medium.cpp b/tdeioslave/media/libmediacommon/medium.cpp index 77e32ba0f..797c409b4 100644 --- a/tdeioslave/media/libmediacommon/medium.cpp +++ b/tdeioslave/media/libmediacommon/medium.cpp @@ -23,68 +23,58 @@ const TQString Medium::SEPARATOR = "---"; +void Medium::initMedium() +{ + m_properties.clear(); + m_properties += TQString::null; // ID + m_properties += TQString::null; // UUID + m_properties += TQString::null; // NAME + m_properties += TQString::null; // LABEL + m_properties += TQString::null; // USER_LABEL + m_properties += "false"; // MOUNTABLE + m_properties += TQString::null; // DEVICE_NODE + m_properties += TQString::null; // MOUNT_POINT + m_properties += TQString::null; // FS_TYPE + m_properties += "false"; // MOUNTED + m_properties += TQString::null; // BASE_URL + m_properties += TQString::null; // MIME_TYPE + m_properties += TQString::null; // ICON_NAME + m_properties += "false"; // ENCRYPTED + m_properties += TQString::null; // CLEAR_DEVICE_UDI + m_properties += "false"; // HIDDEN + m_properties += "false"; // SOFT_HIDDEN + m_properties += "false"; // LOCKED +} + Medium::Medium(const TQString id, TQString uuid, const TQString name) { - m_properties+= id; /* ID */ - m_properties+= uuid; /* UUID */ - m_properties+= name; /* NAME */ - m_properties+= name; /* LABEL */ - m_properties+= TQString::null; /* USER_LABEL */ - - m_properties+= "false"; /* MOUNTABLE */ - m_properties+= TQString::null; /* DEVICE_NODE */ - m_properties+= TQString::null; /* MOUNT_POINT */ - m_properties+= TQString::null; /* FS_TYPE */ - m_properties+= "false"; /* MOUNTED */ - m_properties+= TQString::null; /* BASE_URL */ - m_properties+= TQString::null; /* MIME_TYPE */ - m_properties+= TQString::null; /* ICON_NAME */ - m_properties+= "false"; /* ENCRYPTED */ - m_properties+= TQString::null; /* CLEAR_DEVICE_UDI */ - m_properties+= "false"; /* HIDDEN */ - m_properties+= "false"; /* SOFT_HIDDEN */ - - loadUserLabel(); - - m_halmounted = false; + initMedium(); + if (!id.isEmpty() && !uuid.isEmpty()) + { + m_properties[ID] = id; + m_properties[UUID] = uuid; + m_properties[NAME] = name; + m_properties[LABEL] = name; + loadUserLabel(); + } } Medium::Medium() { - m_properties+= TQString::null; /* ID */ - m_properties+= TQString::null; /* UUID */ - m_properties+= TQString::null; /* NAME */ - m_properties+= TQString::null; /* LABEL */ - m_properties+= TQString::null; /* USER_LABEL */ - - m_properties+= TQString::null; /* MOUNTABLE */ - m_properties+= TQString::null; /* DEVICE_NODE */ - m_properties+= TQString::null; /* MOUNT_POINT */ - m_properties+= TQString::null; /* FS_TYPE */ - m_properties+= TQString::null; /* MOUNTED */ - m_properties+= TQString::null; /* BASE_URL */ - m_properties+= TQString::null; /* MIME_TYPE */ - m_properties+= TQString::null; /* ICON_NAME */ - m_properties+= TQString::null; /* ENCRYPTED */ - m_properties+= TQString::null; /* CLEAR_DEVICE_UDI */ - m_properties+= "false"; /* HIDDEN */ - m_properties+= "false"; /* SOFT_HIDDEN */ - - m_halmounted = false; + initMedium(); } const Medium Medium::create(const TQStringList &properties) { Medium m; - if ( properties.size() >= PROPERTIES_COUNT ) + if (properties.size() >= PROPERTIES_COUNT) { m.m_properties[ID] = properties[ID]; m.m_properties[UUID] = properties[UUID]; m.m_properties[NAME] = properties[NAME]; m.m_properties[LABEL] = properties[LABEL]; m.m_properties[USER_LABEL] = properties[USER_LABEL]; - m.m_properties[MOUNTABLE] = properties[MOUNTABLE]; m.m_properties[DEVICE_NODE] = properties[DEVICE_NODE]; m.m_properties[MOUNT_POINT] = properties[MOUNT_POINT]; @@ -97,6 +87,7 @@ const Medium Medium::create(const TQStringList &properties) m.m_properties[CLEAR_DEVICE_UDI] = properties[CLEAR_DEVICE_UDI]; m.m_properties[HIDDEN] = properties[HIDDEN]; m.m_properties[SOFT_HIDDEN] = properties[SOFT_HIDDEN]; + m.m_properties[LOCKED] = properties[LOCKED]; } return m; @@ -106,13 +97,12 @@ Medium::MList Medium::createList(const TQStringList &properties) { MList l; - if ( properties.size() % (PROPERTIES_COUNT+1) == 0) + if (properties.size() % (PROPERTIES_COUNT+1) == 0) { - int media_count = properties.size()/(PROPERTIES_COUNT+1); - + int media_count = properties.size() / (PROPERTIES_COUNT + 1); TQStringList props = properties; - for(int i=0; i<media_count; i++) + for (int i=0; i < media_count; i++) { const Medium m = create(props); l.append(m); @@ -127,7 +117,6 @@ Medium::MList Medium::createList(const TQStringList &properties) return l; } - void Medium::setName(const TQString &name) { m_properties[NAME] = name; @@ -138,35 +127,22 @@ void Medium::setLabel(const TQString &label) m_properties[LABEL] = label; } -void Medium::setEncrypted(bool state) -{ - m_properties[ENCRYPTED] = ( state ? "true" : "false" ); -} - -void Medium::setHidden(bool state) -{ - m_properties[HIDDEN] = ( state ? "true" : "false" ); -} - -void Medium::setSoftHidden(bool state) -{ - m_properties[SOFT_HIDDEN] = ( state ? "true" : "false" ); -} - void Medium::setUserLabel(const TQString &label) { TDEConfig cfg("mediamanagerrc"); cfg.setGroup("UserLabels"); TQString entry_name = m_properties[UUID]; - - if ( label.isNull() ) - { - cfg.deleteEntry(entry_name); - } - else + if (!entry_name.isEmpty()) { - cfg.writeEntry(entry_name, label); + if (label.isEmpty()) + { + cfg.deleteEntry(entry_name); + } + else + { + cfg.writeEntry(entry_name, label); + } } m_properties[USER_LABEL] = label; @@ -178,10 +154,9 @@ void Medium::loadUserLabel() cfg.setGroup("UserLabels"); TQString entry_name = m_properties[UUID]; - - if ( cfg.hasKey(entry_name) ) + if (!entry_name.isEmpty()) { - m_properties[USER_LABEL] = cfg.readEntry(entry_name); + m_properties[USER_LABEL] = cfg.readEntry(entry_name, TQString::null); } else { @@ -189,48 +164,52 @@ void Medium::loadUserLabel() } } - -bool Medium::mountableState(bool mounted) +void Medium::setMountable(bool mountable) { - if ( m_properties[DEVICE_NODE].isEmpty() - || ( mounted && m_properties[MOUNT_POINT].isEmpty() ) ) + m_properties[MOUNTABLE] = mountable ? "true" : "false"; + if (!mountable) { - return false; + setMountPoint(TQString::null); + setMounted(false); } +} - m_properties[MOUNTABLE] = "true"; - m_properties[MOUNTED] = ( mounted ? "true" : "false" ); +void Medium::setDeviceNode(const TQString &deviceNode) +{ + m_properties[DEVICE_NODE] = deviceNode; +} - return true; +void Medium::setMountPoint(const TQString &mountPoint) +{ + if (isMountable()) + { + m_properties[MOUNT_POINT] = mountPoint; + } + else + { + m_properties[MOUNT_POINT] = TQString::null; + } } -void Medium::mountableState(const TQString &deviceNode, - const TQString &mountPoint, - const TQString &fsType, bool mounted) +void Medium::setFsType(const TQString &fsType) { - m_properties[MOUNTABLE] = "true"; - m_properties[DEVICE_NODE] = deviceNode; - m_properties[MOUNT_POINT] = mountPoint; m_properties[FS_TYPE] = fsType; - m_properties[MOUNTED] = ( mounted ? "true" : "false" ); } -void Medium::mountableState(const TQString &deviceNode, - const TQString &clearDeviceUdi, - const TQString &mountPoint, - const TQString &fsType, bool mounted) +void Medium::setMounted(bool mounted) { - m_properties[MOUNTABLE] = "true"; - m_properties[DEVICE_NODE] = deviceNode; - m_properties[CLEAR_DEVICE_UDI] = clearDeviceUdi; - m_properties[MOUNT_POINT] = mountPoint; - m_properties[FS_TYPE] = fsType; - m_properties[MOUNTED] = ( mounted ? "true" : "false" ); + if (isMountable()) + { + m_properties[MOUNTED] = mounted ? "true" : "false"; + } + else + { + m_properties[MOUNTED] = "false"; + } } -void Medium::unmountableState(const TQString &baseURL) +void Medium::setBaseURL(const TQString &baseURL) { - m_properties[MOUNTABLE] = "false"; m_properties[BASE_URL] = baseURL; } @@ -244,33 +223,51 @@ void Medium::setIconName(const TQString &iconName) m_properties[ICON_NAME] = iconName; } -bool Medium::needMounting() const +void Medium::setEncrypted(bool encrypted) +{ + m_properties[ENCRYPTED] = encrypted ? "true" : "false"; + if (!encrypted) + { + setLocked(false); + } +} + +void Medium::setClearDeviceUdi(const TQString &clearDeviceUdi) { - return isMountable() && !isMounted(); + m_properties[CLEAR_DEVICE_UDI] = clearDeviceUdi; } -bool Medium::needDecryption() const +void Medium::setHidden(bool state) { - return isEncrypted() && clearDeviceUdi().isEmpty(); + m_properties[HIDDEN] = state ? "true" : "false"; +} + +void Medium::setSoftHidden(bool state) +{ + m_properties[SOFT_HIDDEN] = state ? "true" : "false"; +} + +void Medium::setLocked(bool locked) +{ + m_properties[LOCKED] = locked ? "true" : "false"; } KURL Medium::prettyBaseURL() const { - if ( !baseURL().isEmpty() ) - return baseURL(); + if (!baseURL().isEmpty()) + { + return baseURL(); + } - return KURL( mountPoint() ); + return KURL(mountPoint()); } TQString Medium::prettyLabel() const { - if ( !userLabel().isEmpty() ) + if (!userLabel().isEmpty()) { return userLabel(); } - else - { - return label(); - } -} + return label(); +} diff --git a/tdeioslave/media/libmediacommon/medium.h b/tdeioslave/media/libmediacommon/medium.h index bf465fd09..3c9677c21 100644 --- a/tdeioslave/media/libmediacommon/medium.h +++ b/tdeioslave/media/libmediacommon/medium.h @@ -29,24 +29,25 @@ class Medium public: typedef TQValueList<Medium> MList; - static const uint ID = 0; - static const uint UUID = 1; - static const uint NAME = 2; - static const uint LABEL = 3; - static const uint USER_LABEL = 4; - static const uint MOUNTABLE = 5; - static const uint DEVICE_NODE = 6; - static const uint MOUNT_POINT = 7; - static const uint FS_TYPE = 8; - static const uint MOUNTED = 9; - static const uint BASE_URL = 10; - static const uint MIME_TYPE = 11; - static const uint ICON_NAME = 12; - static const uint ENCRYPTED = 13; - static const uint CLEAR_DEVICE_UDI = 14; - static const uint HIDDEN = 15; - static const uint SOFT_HIDDEN = 16; - static const uint PROPERTIES_COUNT = 17; + static const uint ID = 0; + static const uint UUID = 1; + static const uint NAME = 2; + static const uint LABEL = 3; + static const uint USER_LABEL = 4; + static const uint MOUNTABLE = 5; + static const uint DEVICE_NODE = 6; + static const uint MOUNT_POINT = 7; + static const uint FS_TYPE = 8; + static const uint MOUNTED = 9; + static const uint BASE_URL = 10; + static const uint MIME_TYPE = 11; + static const uint ICON_NAME = 12; + static const uint ENCRYPTED = 13; + static const uint CLEAR_DEVICE_UDI = 14; + static const uint HIDDEN = 15; + static const uint SOFT_HIDDEN = 16; + static const uint LOCKED = 17; + static const uint PROPERTIES_COUNT = 18; static const TQString SEPARATOR; Medium(const TQString id, TQString uuid, const TQString name); @@ -60,71 +61,67 @@ public: TQString name() const { return m_properties[NAME]; } TQString label() const { return m_properties[LABEL]; } TQString userLabel() const { return m_properties[USER_LABEL]; } - bool isMountable() const { return m_properties[MOUNTABLE]=="true"; } + bool isMountable() const { return m_properties[MOUNTABLE] == "true"; } TQString deviceNode() const { return m_properties[DEVICE_NODE]; } TQString mountPoint() const { return m_properties[MOUNT_POINT]; } TQString fsType() const { return m_properties[FS_TYPE]; } - bool isMounted() const { return m_properties[MOUNTED]=="true"; } + bool isMounted() const { return m_properties[MOUNTED] == "true"; } TQString baseURL() const { return m_properties[BASE_URL]; } TQString mimeType() const { return m_properties[MIME_TYPE]; } TQString iconName() const { return m_properties[ICON_NAME]; } - bool isEncrypted() const { return m_properties[ENCRYPTED]=="true"; }; + bool isEncrypted() const { return m_properties[ENCRYPTED] == "true"; }; TQString clearDeviceUdi() const { return m_properties[CLEAR_DEVICE_UDI]; }; - bool hidden() const { return m_properties[HIDDEN]=="true"; }; - bool softHidden() const { return m_properties[SOFT_HIDDEN]=="true"; }; + bool hidden() const { return m_properties[HIDDEN] == "true"; }; + bool softHidden() const { return m_properties[SOFT_HIDDEN] == "true"; }; + bool isLocked() const { return m_properties[LOCKED] == "true"; }; - bool needMounting() const; - bool needDecryption() const; + bool needMounting() const { return isMountable() && !isMounted(); }; + bool needUnlocking() const { return isEncrypted() && isLocked(); } KURL prettyBaseURL() const; TQString prettyLabel() const; void setName(const TQString &name); void setLabel(const TQString &label); void setUserLabel(const TQString &label); - void setEncrypted(bool state); - void setHidden(bool state); - void setSoftHidden(bool state); - - bool mountableState(bool mounted); - void mountableState(const TQString &deviceNode, - const TQString &mountPoint, - const TQString &fsType, bool mounted); - void mountableState(const TQString &deviceNode, - const TQString &clearDeviceUdi, - const TQString &mountPoint, - const TQString &fsType, bool mounted); - void unmountableState(const TQString &baseURL = TQString::null); - + void setMountable(bool mountable); + void setDeviceNode(const TQString &deviceNode); + void setMountPoint(const TQString &mountPoint); + void setFsType(const TQString &fsType); + void setMounted(bool mounted); + void setBaseURL(const TQString &baseURL); void setMimeType(const TQString &mimeType); void setIconName(const TQString &iconName); - void setHalMounted(bool flag) const { m_halmounted = flag; } - bool halMounted() const { return m_halmounted; } + void setEncrypted(bool encrypted); + void setClearDeviceUdi(const TQString &clearDeviceUdi); + void setHidden(bool state); + void setSoftHidden(bool state); + void setLocked(bool locked); -//private: Medium(); private: + void initMedium(); void loadUserLabel(); TQStringList m_properties; - mutable bool m_halmounted; -friend class TQValueListNode<const Medium>; + friend class TQValueListNode<const Medium>; }; namespace MediaManagerUtils { - static inline TQMap<TQString,TQString> splitOptions(const TQStringList & options) - { - TQMap<TQString,TQString> valids; - - for (TQStringList::ConstIterator it = options.begin(); it != options.end(); ++it) + static inline TQMap<TQString,TQString> splitOptions(const TQStringList &options) { - TQString key = (*it).left((*it).find('=')); - TQString value = (*it).mid((*it).find('=') + 1); - valids[key] = value; + TQMap<TQString,TQString> valids; + + for (TQStringList::ConstIterator it = options.begin(); it != options.end(); ++it) + { + int pos = (*it).find('='); + TQString key = (*it).left(pos); + TQString value = (*it).mid(pos + 1); + valids[key] = value; + } + return valids; } - return valids; - } } #endif diff --git a/tdeioslave/media/libmediacommon/notifieraction.cpp b/tdeioslave/media/libmediacommon/notifieraction.cpp index 5222b9e65..8eaafcd81 100644 --- a/tdeioslave/media/libmediacommon/notifieraction.cpp +++ b/tdeioslave/media/libmediacommon/notifieraction.cpp @@ -57,8 +57,7 @@ TQPixmap NotifierAction::pixmap() const } else { - TQString path = TDEGlobal::iconLoader()->iconPath( m_iconName, -32 ); - return TQPixmap( path ); + return TDEGlobal::iconLoader()->loadIcon(m_iconName, TDEIcon::NoGroup, TDEIcon::SizeSmall); } } diff --git a/tdeioslave/media/mediaimpl.cpp b/tdeioslave/media/mediaimpl.cpp index b92757f90..510437072 100644 --- a/tdeioslave/media/mediaimpl.cpp +++ b/tdeioslave/media/mediaimpl.cpp @@ -127,7 +127,6 @@ bool MediaImpl::statMediumByLabel(const TQString &label, TDEIO::UDSEntry &entry) return statMedium(name, entry); } - bool MediaImpl::listMedia(TQValueList<TDEIO::UDSEntry> &list) { kdDebug(1219) << "MediaImpl::listMedia" << endl; @@ -149,7 +148,7 @@ bool MediaImpl::listMedia(TQValueList<TDEIO::UDSEntry> &list) Medium::MList::const_iterator it = media.begin(); Medium::MList::const_iterator end = media.end(); - for(; it!=end; ++it) + for(; it != end; ++it) { if (!(*it).hidden()) { entry.clear(); @@ -231,15 +230,6 @@ bool MediaImpl::ensureMediumMounted(Medium &medium) return false; } -#ifdef COMPILE_HALBACKEND - if ( medium.isEncrypted() && medium.clearDeviceUdi().isEmpty() ) - { - m_lastErrorCode = TDEIO::ERR_COULD_NOT_MOUNT; - m_lastErrorMessage = i18n("The drive is encrypted."); - return false; - } -#endif // COMPILE_HALBACKEND - if ( medium.needMounting() ) { m_lastErrorCode = 0; @@ -252,10 +242,10 @@ bool MediaImpl::ensureMediumMounted(Medium &medium) medium.deviceNode(), medium.mountPoint()); job->setAutoWarningHandlingEnabled(false); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotMountResult( TDEIO::Job * ) ) ); - connect( job, TQT_SIGNAL( warning( TDEIO::Job *, const TQString & ) ), - this, TQT_SLOT( slotWarning( TDEIO::Job *, const TQString & ) ) ); + connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ), + this, TQ_SLOT( slotMountResult( TDEIO::Job * ) ) ); + connect( job, TQ_SIGNAL( warning( TDEIO::Job *, const TQString & ) ), + this, TQ_SLOT( slotWarning( TDEIO::Job *, const TQString & ) ) ); */ kapp->dcopClient() ->connectDCOPSignal("kded", "mediamanager", @@ -366,14 +356,19 @@ void MediaImpl::slotStatResult(TDEIO::Job *job) TDEIO::UDSEntry MediaImpl::extractUrlInfos(const KURL &url) { + if (url.isEmpty()) + { + return TDEIO::UDSEntry(); + } + m_entryBuffer.clear(); TDEIO::StatJob *job = TDEIO::stat(url, false); job->setAutoWarningHandlingEnabled( false ); - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( slotStatResult(TDEIO::Job *) ) ); - connect( job, TQT_SIGNAL( warning( TDEIO::Job *, const TQString & ) ), - this, TQT_SLOT( slotWarning( TDEIO::Job *, const TQString & ) ) ); + connect( job, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( slotStatResult(TDEIO::Job *) ) ); + connect( job, TQ_SIGNAL( warning( TDEIO::Job *, const TQString & ) ), + this, TQ_SLOT( slotWarning( TDEIO::Job *, const TQString & ) ) ); tqApp->eventLoop()->enterLoop(); TDEIO::UDSEntry::iterator it = m_entryBuffer.begin(); @@ -449,7 +444,7 @@ void MediaImpl::createMediumEntry(TDEIO::UDSEntry& entry, else { KURL url = medium.prettyBaseURL(); - entry+= extractUrlInfos(url); + entry += extractUrlInfos(url); } } diff --git a/tdeioslave/media/mediaimpl.h b/tdeioslave/media/mediaimpl.h index 1080d6783..a7416f0e5 100644 --- a/tdeioslave/media/mediaimpl.h +++ b/tdeioslave/media/mediaimpl.h @@ -32,7 +32,7 @@ class MediaImpl : public TQObject, public DCOPObject { -Q_OBJECT +TQ_OBJECT K_DCOP public: MediaImpl(); diff --git a/tdeioslave/media/mediamanager/CMakeLists.txt b/tdeioslave/media/mediamanager/CMakeLists.txt index fd0c0f09b..b052bff87 100644 --- a/tdeioslave/media/mediamanager/CMakeLists.txt +++ b/tdeioslave/media/mediamanager/CMakeLists.txt @@ -16,13 +16,10 @@ include_directories( ${CMAKE_BINARY_DIR} ${TDE_INCLUDE_DIR} ${TQT_INCLUDE_DIRS} - ${HAL_INCLUDE_DIRS} - ${DBUS_TQT_INCLUDE_DIRS} ) link_directories( ${TQT_LIBRARY_DIRS} - ${DBUS_TQT_LIBRARY_DIRS} ) @@ -45,11 +42,6 @@ tde_create_translated_desktop( set( target kded_mediamanager ) -if( WITH_HAL ) - set( HAL_MEDIA_BACKEND halbackend.cpp linuxcdpolling.cpp ) - set( HAL_MEDIA_LIBRARIES ${HAL_LIBRARIES} -lhal-storage ${DBUS_TQT_LIBRARIES} ) -endif( ) - if( WITH_TDEHWLIB ) set( TDEHWBACKEND tdehardwarebackend.cpp ) endif( WITH_TDEHWLIB ) @@ -60,7 +52,7 @@ tde_add_kpart( ${target} AUTOMOC backendbase.cpp fstabbackend.cpp removablebackend.cpp unlockdialog.ui dialog.cpp mediadirnotify.cpp mediadirnotify.skel - ${HAL_MEDIA_BACKEND} ${TDEHWBACKEND} - LINK mediacommon-static tdeinit_kded-shared ${HAL_MEDIA_LIBRARIES} + ${TDEHWBACKEND} + LINK mediacommon-static tdeinit_kded-shared ${TDEHW_LIBRARIES} DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/media/mediamanager/Makefile.am b/tdeioslave/media/mediamanager/Makefile.am index 489226e8e..87a20cb89 100644 --- a/tdeioslave/media/mediamanager/Makefile.am +++ b/tdeioslave/media/mediamanager/Makefile.am @@ -1,18 +1,7 @@ kde_module_LTLIBRARIES = kded_mediamanager.la -if include_media_halbackend -HALBACKEND_INCS = $(HAL_INCS) $(DBUS_INCS) $(DBUSTQT_INCS) -endif - METASOURCES = AUTO -INCLUDES = -I$(srcdir)/../libmediacommon -I../libmediacommon $(HALBACKEND_INCS) $(all_includes) - -if include_media_halbackend -HALBACKEND_LIB = libhalbackend.la -libhalbackend_la_SOURCES = halbackend.cpp -libhalbackend_la_LDFLAGS = -avoid-version $(all_libraries) -no-undefined -libhalbackend_la_LIBADD = $(HAL_LIBS) $(DBUS_LIBS) $(DBUSTQT_LIBS) -endif +INCLUDES = -I$(srcdir)/../libmediacommon -I../libmediacommon $(all_includes) if include_media_linuxcdpolling LINUXCDPOLLING_LIB = liblinuxcdpolling.la @@ -20,11 +9,11 @@ liblinuxcdpolling_la_SOURCES = linuxcdpolling.cpp liblinuxcdpolling_la_LDFLAGS = -avoid-version $(all_libraries) -no-undefined endif -noinst_LTLIBRARIES = $(LINUXCDPOLLING_LIB) $(HALBACKEND_LIB) +noinst_LTLIBRARIES = $(LINUXCDPOLLING_LIB) kded_mediamanager_la_SOURCES = mediamanager.cpp mediamanager.skel medialist.cpp backendbase.cpp fstabbackend.cpp removablebackend.cpp mediadirnotify.cpp mediadirnotify.skel kded_mediamanager_la_LDFLAGS = $(all_libraries) -module -avoid-version -kded_mediamanager_la_LIBADD = $(LIB_TDESYCOCA) ../libmediacommon/libmediacommon.la $(HALBACKEND_LIB) $(LINUXCDPOLLING_LIB) +kded_mediamanager_la_LIBADD = $(LIB_TDESYCOCA) ../libmediacommon/libmediacommon.la $(LINUXCDPOLLING_LIB) servicesdir = $(kde_servicesdir)/kded diff --git a/tdeioslave/media/mediamanager/dialog.cpp b/tdeioslave/media/mediamanager/dialog.cpp index 5f655ccce..ddfd041a0 100644 --- a/tdeioslave/media/mediamanager/dialog.cpp +++ b/tdeioslave/media/mediamanager/dialog.cpp @@ -23,7 +23,7 @@ #include "dialog.h" Dialog::Dialog(TQString url, TQString iconName) : - KDialogBase(NULL, "Unlock", true, "Unlock Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Unlock"), "unlocked" )) + KDialogBase(NULL, "Unlock", true, i18n("Unlock Storage Device"), (Cancel|User1), User1, false, KGuiItem(i18n("Unlock"), "unlocked" )) { unlockDialog = new UnlockDialog(this); @@ -37,7 +37,7 @@ Dialog::Dialog(TQString url, TQString iconName) : TQPixmap pixmap = TDEGlobal::iconLoader()->loadIcon(iconName, TDEIcon::NoGroup, TDEIcon::SizeLarge); unlockDialog->encryptedIcon->setPixmap( pixmap ); - connect(unlockDialog->passwordEdit, TQT_SIGNAL (textChanged(const TQString &)), this, TQT_SLOT (slotPasswordChanged(const TQString &))); + connect(unlockDialog->passwordEdit, TQ_SIGNAL (textChanged(const TQString &)), this, TQ_SLOT (slotPasswordChanged(const TQString &))); setMainWidget(unlockDialog); } diff --git a/tdeioslave/media/mediamanager/dialog.h b/tdeioslave/media/mediamanager/dialog.h index 8444ec7dd..1e3dd145c 100644 --- a/tdeioslave/media/mediamanager/dialog.h +++ b/tdeioslave/media/mediamanager/dialog.h @@ -41,7 +41,7 @@ class KryptoMedia; class Dialog : public KDialogBase { -Q_OBJECT +TQ_OBJECT public: Dialog(TQString url, TQString iconName); diff --git a/tdeioslave/media/mediamanager/fstabbackend.cpp b/tdeioslave/media/mediamanager/fstabbackend.cpp index 8eca21771..2bd528c19 100644 --- a/tdeioslave/media/mediamanager/fstabbackend.cpp +++ b/tdeioslave/media/mediamanager/fstabbackend.cpp @@ -61,8 +61,8 @@ FstabBackend::FstabBackend(MediaList &list, bool networkSharesOnly) KDirWatch::self()->addFile(MTAB); KDirWatch::self()->addFile(FSTAB); - connect( KDirWatch::self(), TQT_SIGNAL( dirty(const TQString&) ), - this, TQT_SLOT( slotDirty(const TQString&) ) ); + connect( KDirWatch::self(), TQ_SIGNAL( dirty(const TQString&) ), + this, TQ_SLOT( slotDirty(const TQString&) ) ); handleFstabChange(false); handleMtabChange(false); @@ -70,8 +70,8 @@ FstabBackend::FstabBackend(MediaList &list, bool networkSharesOnly) KDirWatch::self()->startScan(); #if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) - connect( &m_mtabTimer, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( handleMtabChange() ) ); + connect( &m_mtabTimer, TQ_SIGNAL( timeout() ), + this, TQ_SLOT( handleMtabChange() ) ); m_mtabTimer.start(250); #endif } @@ -160,7 +160,6 @@ bool inExclusionPattern(KMountPoint *mount, bool networkSharesOnly) || mount->mountPoint().find("/sys") == 0 // We might want to display only network shares - // since HAL doesn't handle them || ( networkSharesOnly && mount->mountType().find( "smb" ) == -1 && mount->mountType().find( "cifs" ) == -1 @@ -220,7 +219,11 @@ void FstabBackend::handleMtabChange(bool allowNotification) Medium *m = new Medium(id, name); - m->mountableState(dev, mp, fs, true); + m->setMountable(true); + m->setDeviceNode(dev); + m->setMountPoint(mp); + m->setFsType(fs); + m->setMounted(true); TQString mime, icon, label; guess(dev, mp, fs, true, mime, icon, label); @@ -293,7 +296,11 @@ void FstabBackend::handleFstabChange(bool allowNotification) Medium *m = new Medium(id, id, name); - m->mountableState(dev, mp, fs, false); + m->setMountable(true); + m->setDeviceNode(dev); + m->setMountPoint(mp); + m->setFsType(fs); + m->setMounted(false); TQString mime, icon, label; guess(dev, mp, fs, false, mime, icon, label); diff --git a/tdeioslave/media/mediamanager/fstabbackend.h b/tdeioslave/media/mediamanager/fstabbackend.h index 0aed11333..0f4b3b85e 100644 --- a/tdeioslave/media/mediamanager/fstabbackend.h +++ b/tdeioslave/media/mediamanager/fstabbackend.h @@ -31,7 +31,7 @@ class FstabBackend : public TQObject, public BackendBase { -Q_OBJECT +TQ_OBJECT public: FstabBackend(MediaList &list, bool networkSharesOnly = false); diff --git a/tdeioslave/media/mediamanager/halbackend.cpp b/tdeioslave/media/mediamanager/halbackend.cpp deleted file mode 100644 index 157f89212..000000000 --- a/tdeioslave/media/mediamanager/halbackend.cpp +++ /dev/null @@ -1,1961 +0,0 @@ -/* This file is part of the KDE Project - Copyright (c) 2004-2005 Jérôme Lodewyck <jerome dot lodewyck at normalesup dot org> - Copyright (c) 2006 Valentine Sinitsyn <e_val@inbox.ru> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "halbackend.h" -#include "linuxcdpolling.h" - -#include <stdlib.h> -#include <locale.h> - -#include <tdeapplication.h> -#include <tdemessagebox.h> -#include <tqeventloop.h> -#include <tqfile.h> -#include <tdelocale.h> -#include <kurl.h> -#include <kdebug.h> -#include <kprocess.h> -#include <tdeconfig.h> -#include <tqstylesheet.h> -#include <kmountpoint.h> -#include <tdemessagebox.h> -#include <tdeio/job.h> -#include <kprotocolinfo.h> -#include <kstandarddirs.h> -#include <kprocess.h> - -#define MOUNT_MEDIA_SUFFIX (medium->isEncrypted() ? \ - (TQString("_encrypted") + (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt) ? "_unlocked" : "_locked")) : \ - (medium->isMounted() ? TQString("_mounted") : TQString("_unmounted"))) - -#define MOUNTED_ICON_SUFFIX (medium->isEncrypted() ? \ - (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt) ? "-unlocked" : "-locked") : \ - (medium->isMounted() ? TQString("-mounted") : TQString("-unmounted"))) - -/* Static instance of this class, for static HAL callbacks */ -static HALBackend* s_HALBackend; - -/* A macro function to convert HAL string properties to TQString */ -TQString libhal_device_get_property_QString(LibHalContext *ctx, const char* udi, const char *key) -{ - char* _ppt_string; - TQString _ppt_QString; - _ppt_string = libhal_device_get_property_string(ctx, udi, key, NULL); - if ( _ppt_string ) - _ppt_QString = _ppt_string; - libhal_free_string(_ppt_string); - return _ppt_QString; -} - -/* Constructor */ -HALBackend::HALBackend(MediaList &list, TQObject* parent) - : TQObject() - , BackendBase(list) - , m_halContext(NULL) - , m_halStoragePolicy(NULL) - , m_parent(parent) -{ - s_HALBackend = this; -} - -/* Destructor */ -HALBackend::~HALBackend() -{ - /* Close HAL connection */ - if (m_halContext) - { - const TQPtrList<Medium> medlist = m_mediaList.list(); - TQPtrListIterator<Medium> it (medlist); - for ( const Medium *current_medium = it.current(); current_medium; current_medium = ++it) - { - if( !current_medium->id().startsWith( "/org/kde" )) - unmount(current_medium->id()); - } - - - /* Remove all the registered media first */ - int numDevices; - char** halDeviceList = libhal_get_all_devices( m_halContext, &numDevices, NULL ); - - if ( halDeviceList ) - { - for ( int i = 0; i < numDevices; i++ ) - { - m_mediaList.removeMedium( halDeviceList[i], false ); - } - } - - libhal_free_string_array( halDeviceList ); - - DBusError error; - dbus_error_init(&error); - libhal_ctx_shutdown(m_halContext, &error); - libhal_ctx_free(m_halContext); - } - - if (m_halStoragePolicy) - libhal_storage_policy_free(m_halStoragePolicy); -} - -/* Connect to the HAL */ -bool HALBackend::InitHal() -{ - kdDebug(1219) << "Context new" << endl; - m_halContext = libhal_ctx_new(); - if (!m_halContext) - { - kdDebug(1219) << "Failed to initialize HAL!" << endl; - return false; - } - - // Main loop integration - kdDebug(1219) << "Main loop integration" << endl; - DBusError error; - dbus_error_init(&error); - dbus_connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); - - if (!dbus_connection || dbus_error_is_set(&error)) { - dbus_error_free(&error); - libhal_ctx_free(m_halContext); - m_halContext = NULL; - return false; - } - - dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE); - - MainLoopIntegration(dbus_connection); - libhal_ctx_set_dbus_connection(m_halContext, dbus_connection); - - // HAL callback functions - kdDebug(1219) << "Callback functions" << endl; - libhal_ctx_set_device_added(m_halContext, HALBackend::hal_device_added); - libhal_ctx_set_device_removed(m_halContext, HALBackend::hal_device_removed); - libhal_ctx_set_device_new_capability (m_halContext, NULL); - libhal_ctx_set_device_lost_capability (m_halContext, NULL); - libhal_ctx_set_device_property_modified (m_halContext, HALBackend::hal_device_property_modified); - libhal_ctx_set_device_condition(m_halContext, HALBackend::hal_device_condition); - - kdDebug(1219) << "Context Init" << endl; - if (!libhal_ctx_init(m_halContext, &error)) - { - if (dbus_error_is_set(&error)) - dbus_error_free(&error); - libhal_ctx_free(m_halContext); - m_halContext = NULL; - kdDebug(1219) << "Failed to init HAL context!" << endl; - return false; - } - - /** @todo customize watch policy */ - kdDebug(1219) << "Watch properties" << endl; - if (!libhal_device_property_watch_all(m_halContext, &error)) - { - kdDebug(1219) << "Failed to watch HAL properties!" << endl; - return false; - } - - /* libhal-storage initialization */ - kdDebug(1219) << "Storage Policy" << endl; - m_halStoragePolicy = libhal_storage_policy_new(); - /** @todo define libhal-storage icon policy */ - - /* List devices at startup */ - return ListDevices(); -} - -/* List devices (at startup)*/ -bool HALBackend::ListDevices() -{ - kdDebug(1219) << "ListDevices" << endl; - - int numDevices; - char** halDeviceList = libhal_get_all_devices(m_halContext, &numDevices, NULL); - - if (!halDeviceList) - return false; - - kdDebug(1219) << "HALBackend::ListDevices : " << numDevices << " devices found" << endl; - for (int i = 0; i < numDevices; i++) - AddDevice(halDeviceList[i], false); - - libhal_free_string_array( halDeviceList ); - - return true; -} - -/* Create a media instance for the HAL device "udi". - This functions checks whether the device is worth listing */ -void HALBackend::AddDevice(const char *udi, bool allowNotification) -{ - /* We don't deal with devices that do not expose their capabilities. - If we don't check this, we will get a lot of warning messages from libhal */ - if (!libhal_device_property_exists(m_halContext, udi, "info.capabilities", NULL)) - return; - - /* If the device is already listed, do not process. - This should not happen, but who knows... */ - /** @todo : refresh properties instead ? */ - if (m_mediaList.findById(udi)) - return; - - if (libhal_device_get_property_bool(m_halContext, "/org/freedesktop/Hal/devices/computer", "storage.disable_volume_handling", NULL)) - allowNotification=false; - - /* Add volume block devices */ - if (libhal_device_query_capability(m_halContext, udi, "volume", NULL)) - { - /* We only list volumes that... - * - are encrypted with LUKS or - * - have a filesystem or - * - have an audio track - */ - if ( ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "crypto" || - libhal_device_get_property_QString(m_halContext, udi, "volume.fstype") != "crypto_LUKS" - ) && - libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") != "filesystem" && - !libhal_device_get_property_bool(m_halContext, udi, "volume.disc.has_audio", NULL) && - !libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_blank", NULL) ) - return; - - /* Query drive udi */ - TQString driveUdi = libhal_device_get_property_QString(m_halContext, udi, "block.storage_device"); - if ( driveUdi.isNull() ) // no storage - no fun - return; - - // if the device is locked do not act upon it - if (libhal_device_get_property_bool(m_halContext, driveUdi.ascii(), "info.locked", NULL)) - allowNotification=false; - - // if the device is locked do not act upon it - if (libhal_device_get_property_bool(m_halContext, driveUdi.ascii(), "storage.partition_table_changed", NULL)) - allowNotification=false; - - /** @todo check exclusion list **/ - - /* Special handling for clear crypto volumes */ - LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); - if (!halVolume) - return; - const char* backingVolumeUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume); - if ( backingVolumeUdi != NULL ) - { - /* The crypto drive was unlocked and may now be mounted... */ - kdDebug(1219) << "HALBackend::AddDevice : ClearVolume appeared for " << backingVolumeUdi << endl; - ResetProperties(backingVolumeUdi, allowNotification); - libhal_volume_free(halVolume); - return; - } - libhal_volume_free(halVolume); - - /* Create medium */ - Medium* medium = new Medium(udi, udi, ""); - setVolumeProperties(medium); - - if ( isInFstab( medium ).isNull() ) - { - // if it's not mountable by user and not by HAL, don't show it at all - if ( ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") == "filesystem" && - !libhal_device_get_property_bool(m_halContext, udi, "volume.is_mounted", NULL ) ) && - ( libhal_device_get_property_bool(m_halContext, udi, "volume.ignore", NULL ) ) ) - { - delete medium; - return; - } - } - - // instert medium into list - m_mediaList.addMedium(medium, allowNotification); - - // finally check for automount - TQMap<TQString,TQString> options = MediaManagerUtils::splitOptions(mountoptions(udi)); - kdDebug() << "automount " << options["automount"] << endl; - if (options["automount"] == "true" && allowNotification ) { - TQString error = mount(medium); - if (!error.isEmpty()) - kdDebug() << "error " << error << endl; - } - - return; - } - - /* Floppy & zip drives */ - if (libhal_device_query_capability(m_halContext, udi, "storage", NULL)) - if ((libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type") == "floppy") || - (libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type") == "zip") || - (libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type") == "jaz")) - { - if (! libhal_device_get_property_bool(m_halContext, udi, "storage.removable.media_available", NULL) ) - allowNotification = false; - /* Create medium */ - Medium* medium = new Medium(udi, udi, ""); - // if the storage has a volume, we ignore it - if ( setFloppyProperties(medium) ) - m_mediaList.addMedium(medium, allowNotification); - else - delete medium; - return; - } - - /* Camera handled by gphoto2*/ - if (libhal_device_query_capability(m_halContext, udi, "camera", NULL) && - ((libhal_device_get_property_QString(m_halContext, udi, "camera.access_method")=="ptp") || - - (libhal_device_property_exists(m_halContext, udi, "camera.libgphoto2.support", NULL) && - libhal_device_get_property_bool(m_halContext, udi, "camera.libgphoto2.support", NULL))) - ) - { - /* Create medium */ - Medium* medium = new Medium(udi, udi, ""); - setCameraProperties(medium); - m_mediaList.addMedium(medium, allowNotification); - return; - } -} - -void HALBackend::RemoveDevice(const char *udi) -{ - const Medium *medium = m_mediaList.findByClearUdi(udi); - if (medium) { - ResetProperties(medium->id().ascii()); - } else { - m_mediaList.removeMedium(udi, true); - } -} - -void HALBackend::ModifyDevice(const char *udi, const char* key) -{ - kdDebug(1219) << "HALBackend::ModifyDevice for '" << udi << "' on '" << key << "'\n"; - - const char* mediumUdi = findMediumUdiFromUdi(udi); - if (!mediumUdi) - return; - bool allowNotification = false; - if (strcmp(key, "storage.removable.media_available") == 0) - allowNotification = libhal_device_get_property_bool(m_halContext, udi, key, NULL); - ResetProperties(mediumUdi, allowNotification); -} - -void HALBackend::DeviceCondition(const char* udi, const char* condition) -{ - TQString conditionName = TQString(condition); - kdDebug(1219) << "Processing device condition " << conditionName << " for " << udi << endl; - - if (conditionName == "EjectPressed") { - const Medium* medium = m_mediaList.findById(udi); - if (!medium) { - /* the ejectpressed appears on the drive and we need to find the volume */ - const TQPtrList<Medium> medlist = m_mediaList.list(); - TQPtrListIterator<Medium> it (medlist); - for ( const Medium *current_medium = it.current(); current_medium; current_medium = ++it) - { - if( current_medium->id().startsWith( "/org/kde" )) - continue; - TQString driveUdi = libhal_device_get_property_QString(m_halContext, current_medium->id().latin1(), "block.storage_device"); - if (driveUdi == udi) - { - medium = current_medium; - break; - } - } - } - if (medium) { - TDEProcess p; - p << "tdeio_media_mounthelper" << "-e" << medium->name(); - p.start(TDEProcess::DontCare); - } - } - - const char* mediumUdi = findMediumUdiFromUdi(udi); - kdDebug() << "findMedumUdiFromUdi " << udi << " returned " << mediumUdi << endl; - if (!mediumUdi) - return; - - /* TODO: Warn the user that (s)he should unmount devices before unplugging */ - if (conditionName == "VolumeUnmountForced") - ResetProperties(mediumUdi); - - /* Reset properties after mounting */ - if (conditionName == "VolumeMount") - ResetProperties(mediumUdi); - - /* Reset properties after unmounting */ - if (conditionName == "VolumeUnmount") - ResetProperties(mediumUdi); - -} - -void HALBackend::MainLoopIntegration(DBusConnection *dbusConnection) -{ - m_dBusQtConnection = new DBusQt::Connection(m_parent); - m_dBusQtConnection->dbus_connection_setup_with_qt_main(dbusConnection); -} - -/****************************************** - ** Properties attribution ** - ******************************************/ - -/* Return the medium udi that should be updated when recieving a call for - device udi */ -const char* HALBackend::findMediumUdiFromUdi(const char* udi) -{ - /* Easy part : this Udi is already registered as a device */ - const Medium* medium = m_mediaList.findById(udi); - if (medium) - return medium->id().ascii(); - - /* Hard part : this is a volume whose drive is registered */ - if (libhal_device_property_exists(m_halContext, udi, "info.capabilities", NULL)) - if (libhal_device_query_capability(m_halContext, udi, "volume", NULL)) - { - /* check if this belongs to an encrypted volume */ - LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); - if (!halVolume) return NULL; - const char* backingUdi = libhal_volume_crypto_get_backing_volume_udi(halVolume); - if (backingUdi != NULL) { - const char* result = findMediumUdiFromUdi(backingUdi); - libhal_volume_free(halVolume); - return result; - } - libhal_volume_free(halVolume); - - /* this is a volume whose drive is registered */ - TQString driveUdi = libhal_device_get_property_QString(m_halContext, udi, "block.storage_device"); - return findMediumUdiFromUdi(driveUdi.ascii()); - } - - return NULL; -} - -void HALBackend::ResetProperties(const char* mediumUdi, bool allowNotification) -{ - kdDebug(1219) << "HALBackend::setProperties" << endl; - if ( TQString::fromLatin1( mediumUdi ).startsWith( "/org/kde/" ) ) - { - const Medium *cmedium = m_mediaList.findById(mediumUdi); - if ( cmedium ) - { - Medium m( *cmedium ); - if ( setFstabProperties( &m ) ) { - kdDebug() << "setFstabProperties worked" << endl; - m_mediaList.changeMediumState(m, allowNotification); - } - return; - } - } - - Medium* m = new Medium(mediumUdi, mediumUdi, ""); - - if (libhal_device_query_capability(m_halContext, mediumUdi, "volume", NULL)) - setVolumeProperties(m); - if (libhal_device_query_capability(m_halContext, mediumUdi, "storage", NULL)) - setFloppyProperties(m); - if (libhal_device_query_capability(m_halContext, mediumUdi, "camera", NULL)) - setCameraProperties(m); - - m_mediaList.changeMediumState(*m, allowNotification); - - delete m; -} - -void HALBackend::setVolumeProperties(Medium* medium) -{ - kdDebug(1219) << "HALBackend::setVolumeProperties for " << medium->id() << endl; - - const char* udi = medium->id().ascii(); - /* Check if the device still exists */ - if (!libhal_device_exists(m_halContext, udi, NULL)) - return; - - /* Get device information from libhal-storage */ - LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, udi); - if (!halVolume) - return; - TQString driveUdi = libhal_volume_get_storage_device_udi(halVolume); - LibHalDrive* halDrive = 0; - if ( !driveUdi.isNull() ) - halDrive = libhal_drive_from_udi(m_halContext, driveUdi.ascii()); - if (!halDrive) { - // at times HAL sends an UnmountForced event before the device is removed - libhal_volume_free(halVolume); - return; - } - - medium->setName( - generateName(libhal_volume_get_device_file(halVolume)) ); - - LibHalVolume* halClearVolume = NULL; - if ( libhal_device_get_property_QString(m_halContext, udi, "volume.fsusage") == "crypto" ) - { - kdDebug(1219) << "HALBackend::setVolumeProperties : crypto volume" << endl; - - medium->setEncrypted(true); - char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); - TQString clearUdiString; - if (clearUdi != NULL) { - kdDebug(1219) << "HALBackend::setVolumeProperties : crypto clear volume avail - " << clearUdi << endl; - halClearVolume = libhal_volume_from_udi(m_halContext, clearUdi); - // ignore if halClearVolume is NULL -> just not unlocked in this case - clearUdiString = clearUdi; - libhal_free_string(clearUdi); - } - - if (halClearVolume) - medium->mountableState( - libhal_volume_get_device_file(halVolume), /* Device node */ - clearUdiString, - libhal_volume_get_mount_point(halClearVolume), /* Mount point */ - libhal_volume_get_fstype(halClearVolume), /* Filesystem type */ - libhal_volume_is_mounted(halClearVolume) ); /* Mounted ? */ - else - medium->mountableState( - libhal_volume_get_device_file(halVolume), /* Device node */ - TQString::null, - TQString::null, /* Mount point */ - TQString::null, /* Filesystem type */ - false ); /* Mounted ? */ - } - else - { - kdDebug(1219) << "HALBackend::setVolumeProperties : normal volume" << endl; - medium->mountableState( - libhal_volume_get_device_file(halVolume), /* Device node */ - TQString::fromUtf8(libhal_volume_get_mount_point(halVolume)), /* Mount point */ - libhal_volume_get_fstype(halVolume), /* Filesystem type */ - libhal_volume_is_mounted(halVolume) ); /* Mounted ? */ - } - - - char* name = libhal_volume_policy_compute_display_name(halDrive, halVolume, m_halStoragePolicy); - TQString volume_name = TQString::fromUtf8(name); - TQString media_name = volume_name; - /* media_name contains something like "501M Removable Media" or "Blank CD-R" - The former needs special handling for correct translation - */ - if (media_name.find(TQRegExp("^[0-9]+\\.?[0-9]*[KMGT] (Removable )?Media$")) > -1) { - TQString pattern = media_name.section(" ", 1); - media_name.replace(pattern, i18n(pattern.utf8())); - medium->setLabel(media_name); - } else { - medium->setLabel(i18n(media_name.utf8())); - } - - free(name); - - TQString mimeType; - if (libhal_volume_is_disc(halVolume)) - { - mimeType = "media/cdrom" + MOUNT_MEDIA_SUFFIX; - - LibHalVolumeDiscType discType = libhal_volume_get_disc_type(halVolume); - if ((discType == LIBHAL_VOLUME_DISC_TYPE_CDROM) || - (discType == LIBHAL_VOLUME_DISC_TYPE_CDR) || - (discType == LIBHAL_VOLUME_DISC_TYPE_CDRW)) - { - if (libhal_volume_disc_is_blank(halVolume)) - { - mimeType = "media/blankcd"; - medium->unmountableState(""); - } - else - { - mimeType = "media/cdwriter" + MOUNT_MEDIA_SUFFIX; - } - } - else if ((discType == LIBHAL_VOLUME_DISC_TYPE_DVDROM) || (discType == LIBHAL_VOLUME_DISC_TYPE_DVDRAM) || - (discType == LIBHAL_VOLUME_DISC_TYPE_DVDR) || (discType == LIBHAL_VOLUME_DISC_TYPE_DVDRW) || - (discType == LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR) || (discType == LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW) ) - { - if (libhal_volume_disc_is_blank(halVolume)) - { - mimeType = "media/blankdvd"; - medium->unmountableState(""); - } - else - { - mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; - } - } - else if ((discType == LIBHAL_VOLUME_DISC_TYPE_BDROM) || (discType == LIBHAL_VOLUME_DISC_TYPE_BDR) || - (discType == LIBHAL_VOLUME_DISC_TYPE_BDRE) || (discType == LIBHAL_VOLUME_DISC_TYPE_HDDVDROM) || - (discType == LIBHAL_VOLUME_DISC_TYPE_HDDVDR) || (discType == LIBHAL_VOLUME_DISC_TYPE_HDDVDRW) ) - { - if (libhal_volume_disc_is_blank(halVolume)) - { - mimeType = "media/blankbluray"; - medium->unmountableState(""); - } - else - { - mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; - } - } - - if (libhal_volume_disc_has_audio(halVolume) && !libhal_volume_disc_has_data(halVolume)) - { - mimeType = "media/audiocd"; - medium->unmountableState( "audiocd:/?device=" + TQString(libhal_volume_get_device_file(halVolume)) ); - } - - medium->setIconName(TQString::null); - - /* check if the disc id a vcd or a video dvd */ - if (libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_vcd", NULL)) - { - mimeType = "media/vcd"; - } - else if (libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_svcd", NULL)) - { - mimeType = "media/svcd"; - } - else if (libhal_device_get_property_bool(m_halContext, udi, "volume.disc.is_videodvd", NULL)) - { - mimeType = "media/dvdvideo"; - } - - } - else - { - mimeType = "media/hdd" + MOUNT_MEDIA_SUFFIX; - medium->setIconName(TQString::null); // reset icon - if (libhal_drive_is_hotpluggable(halDrive)) - { - mimeType = "media/removable" + MOUNT_MEDIA_SUFFIX; - medium->needMounting(); - switch (libhal_drive_get_type(halDrive)) { - case LIBHAL_DRIVE_TYPE_COMPACT_FLASH: - medium->setIconName("media-flash-compact_flash" + MOUNTED_ICON_SUFFIX); - break; - case LIBHAL_DRIVE_TYPE_MEMORY_STICK: - medium->setIconName("media-flash-memory_stick" + MOUNTED_ICON_SUFFIX); - break; - case LIBHAL_DRIVE_TYPE_SMART_MEDIA: - medium->setIconName("media-flash-smart_media" + MOUNTED_ICON_SUFFIX); - break; - case LIBHAL_DRIVE_TYPE_SD_MMC: - medium->setIconName("media-flash-sd_mmc" + MOUNTED_ICON_SUFFIX); - break; - case LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER: - { - medium->setIconName("ipod" + MOUNTED_ICON_SUFFIX); - - if (libhal_device_get_property_QString(m_halContext, driveUdi.latin1(), "info.product") == "iPod" && - KProtocolInfo::isKnownProtocol( TQString("ipod") ) ) - { - medium->unmountableState( "ipod:/" ); - medium->mountableState( libhal_volume_is_mounted(halVolume) ); - } - break; - } - case LIBHAL_DRIVE_TYPE_CAMERA: - { - mimeType = "media/camera" + MOUNT_MEDIA_SUFFIX; - const char *physdev = libhal_drive_get_physical_device_udi(halDrive); - // get model from camera - if (physdev && libhal_device_query_capability(m_halContext, physdev, "camera", NULL)) - { - if (libhal_device_property_exists(m_halContext, physdev, "usb_device.product", NULL)) - medium->setLabel(libhal_device_get_property_QString(m_halContext, physdev, "usb_device.product")); - else if (libhal_device_property_exists(m_halContext, physdev, "usb.product", NULL)) - medium->setLabel(libhal_device_get_property_QString(m_halContext, physdev, "usb.product")); - } - break; - } - case LIBHAL_DRIVE_TYPE_TAPE: - medium->setIconName("media-tape" + MOUNTED_ICON_SUFFIX); - break; - default: - medium->setIconName(TQString::null); - } - - if (medium->isMounted() && TQFile::exists(medium->mountPoint() + "/dcim")) - { - mimeType = "media/camera" + MOUNT_MEDIA_SUFFIX; - } - } - } - medium->setMimeType(mimeType); - - libhal_drive_free(halDrive); - libhal_volume_free(halVolume); -} - -bool HALBackend::setFstabProperties( Medium *medium ) -{ - TQString mp = isInFstab(medium); - - if (!mp.isNull() && !medium->id().startsWith( "/org/kde" ) ) - { - // now that we know it's in fstab, we have to find out if it's mounted - KMountPoint::List mtab = KMountPoint::currentMountPoints(); - - KMountPoint::List::iterator it = mtab.begin(); - KMountPoint::List::iterator end = mtab.end(); - - bool mounted = false; - - for (; it!=end; ++it) - { - if ((*it)->mountedFrom() == medium->deviceNode() && (*it)->mountPoint() == mp ) - { - mounted = true; - break; - } - } - - kdDebug() << mp << " " << mounted << " " << medium->deviceNode() << " " << endl; - TQString fstype = medium->fsType(); - if ( fstype.isNull() ) - fstype = "auto"; - - medium->mountableState( - medium->deviceNode(), - mp, /* Mount point */ - fstype, /* Filesystem type */ - mounted ); /* Mounted ? */ - - return true; - } - - return false; - -} - -// Handle floppies and zip drives -bool HALBackend::setFloppyProperties(Medium* medium) -{ - kdDebug(1219) << "HALBackend::setFloppyProperties for " << medium->id() << endl; - - const char* udi = medium->id().ascii(); - /* Check if the device still exists */ - if (!libhal_device_exists(m_halContext, udi, NULL)) - return false; - - LibHalDrive* halDrive = libhal_drive_from_udi(m_halContext, udi); - if (!halDrive) - return false; - - TQString drive_type = libhal_device_get_property_QString(m_halContext, udi, "storage.drive_type"); - - if (drive_type == "zip") { - int numVolumes; - char** volumes = libhal_drive_find_all_volumes(m_halContext, halDrive, &numVolumes); - libhal_free_string_array(volumes); - kdDebug(1219) << " found " << numVolumes << " volumes" << endl; - if (numVolumes) - { - libhal_drive_free(halDrive); - return false; - } - } - - medium->setName( generateName(libhal_drive_get_device_file(halDrive)) ); - medium->setLabel(i18n("Unknown Drive")); - - // HAL hates floppies - so we have to do it twice ;( - medium->mountableState(libhal_drive_get_device_file(halDrive), TQString::null, TQString::null, false); - setFloppyMountState(medium); - - if (drive_type == "floppy") - { - if (medium->isMounted()) // don't use _SUFFIX here as it accesses the volume - medium->setMimeType("media/floppy_mounted" ); - else - medium->setMimeType("media/floppy_unmounted"); - medium->setLabel(i18n("Floppy Drive")); - } - else if (drive_type == "zip") - { - if (medium->isMounted()) - medium->setMimeType("media/zip_mounted" ); - else - medium->setMimeType("media/zip_unmounted"); - medium->setLabel(i18n("Zip Drive")); - } - - /** @todo And mimtype for JAZ drives ? */ - - medium->setIconName(TQString::null); - - libhal_drive_free(halDrive); - - return true; -} - -void HALBackend::setFloppyMountState( Medium *medium ) -{ - if ( !medium->id().startsWith( "/org/kde" ) ) - { - KMountPoint::List mtab = KMountPoint::currentMountPoints(); - KMountPoint::List::iterator it = mtab.begin(); - KMountPoint::List::iterator end = mtab.end(); - - TQString fstype; - TQString mountpoint; - for (; it!=end; ++it) - { - if ((*it)->mountedFrom() == medium->deviceNode() ) - { - fstype = (*it)->mountType().isNull() ? (*it)->mountType() : "auto"; - mountpoint = (*it)->mountPoint(); - medium->mountableState( medium->deviceNode(), mountpoint, fstype, true ); - return; - } - } - } -} - -void HALBackend::setCameraProperties(Medium* medium) -{ - kdDebug(1219) << "HALBackend::setCameraProperties for " << medium->id() << endl; - - const char* udi = medium->id().ascii(); - /* Check if the device still exists */ - if (!libhal_device_exists(m_halContext, udi, NULL)) - return; - - /** @todo find name */ - medium->setName("camera"); - - TQString device = "camera:/"; - - char *cam = libhal_device_get_property_string(m_halContext, udi, "camera.libgphoto2.name", NULL); - DBusError error; - dbus_error_init(&error); - if (cam && - libhal_device_property_exists(m_halContext, udi, "usb.linux.device_number", NULL) && - libhal_device_property_exists(m_halContext, udi, "usb.bus_number", NULL)) - device.sprintf("camera://%s@[usb:%03d,%03d]/", cam, - libhal_device_get_property_int(m_halContext, udi, "usb.bus_number", &error), - libhal_device_get_property_int(m_halContext, udi, "usb.linux.device_number", &error)); - - libhal_free_string(cam); - - /** @todo find the rest of this URL */ - medium->unmountableState(device); - medium->setMimeType("media/gphoto2camera"); - medium->setIconName(TQString::null); - if (libhal_device_property_exists(m_halContext, udi, "usb_device.product", NULL)) - medium->setLabel(libhal_device_get_property_QString(m_halContext, udi, "usb_device.product")); - else if (libhal_device_property_exists(m_halContext, udi, "usb.product", NULL)) - medium->setLabel(libhal_device_get_property_QString(m_halContext, udi, "usb.product")); - else - medium->setLabel(i18n("Camera")); -} - -TQString HALBackend::generateName(const TQString &devNode) -{ - return KURL(devNode).fileName(); -} - -/****************************************** - ** HAL CALL-BACKS ** - ******************************************/ - -void HALBackend::hal_device_added(LibHalContext *ctx, const char *udi) -{ - kdDebug(1219) << "HALBackend::hal_device_added " << udi << endl; - Q_UNUSED(ctx); - s_HALBackend->AddDevice(udi); -} - -void HALBackend::hal_device_removed(LibHalContext *ctx, const char *udi) -{ - kdDebug(1219) << "HALBackend::hal_device_removed " << udi << endl; - Q_UNUSED(ctx); - s_HALBackend->RemoveDevice(udi); -} - -void HALBackend::hal_device_property_modified(LibHalContext *ctx, const char *udi, - const char *key, dbus_bool_t is_removed, dbus_bool_t is_added) -{ - kdDebug(1219) << "HALBackend::hal_property_modified " << udi << " -- " << key << endl; - Q_UNUSED(ctx); - Q_UNUSED(is_removed); - Q_UNUSED(is_added); - s_HALBackend->ModifyDevice(udi, key); -} - -void HALBackend::hal_device_condition(LibHalContext *ctx, const char *udi, - const char *condition_name, - const char* message - ) -{ - kdDebug(1219) << "HALBackend::hal_device_condition " << udi << " -- " << condition_name << endl; - Q_UNUSED(ctx); - Q_UNUSED(message); - s_HALBackend->DeviceCondition(udi, condition_name); -} - -TQStringList HALBackend::getHALmountoptions(TQString udi) -{ - const char* _ppt_string; - LibHalVolume* volume; - LibHalDrive* drive; - - TQString _ppt_TQString; - - volume = libhal_volume_from_udi( m_halContext, udi.latin1() ); - if( volume ) - drive = libhal_drive_from_udi( m_halContext, libhal_volume_get_storage_device_udi( volume ) ); - else - drive = libhal_drive_from_udi( m_halContext, udi.latin1() ); - - if( !drive ) - return TQString::null; - - if( volume ) - _ppt_string = libhal_volume_policy_get_mount_options ( drive, volume, NULL ); - else - _ppt_string = libhal_drive_policy_get_mount_options ( drive, NULL ); - - _ppt_TQString = TQString(_ppt_string ? _ppt_string : ""); - - return TQStringList::split(",",_ppt_TQString); -} - -TQStringList HALBackend::mountoptions(const TQString &name) -{ - const Medium* medium = m_mediaList.findById(name); - if (!medium) - return TQStringList(); // we don't know about that one - if (!isInFstab(medium).isNull()) - return TQStringList(); // not handled by HAL - fstab entry - - TQString volume_udi = name; - if (medium->isEncrypted()) { - // see if we have a clear volume - LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); - if (halVolume) { - char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); - if (clearUdi != NULL) { - volume_udi = clearUdi; - libhal_free_string(clearUdi); - } else { - // if not unlocked yet then no mountoptions - return TQStringList(); - } - libhal_volume_free(halVolume); - } else { - // strange... - return TQStringList(); - } - } - - TDEConfig config("mediamanagerrc"); - - bool use_defaults = true; - if (config.hasGroup(name)) - { - config.setGroup(name); - use_defaults = config.readBoolEntry("use_defaults", false); - } - - if (use_defaults) - config.setGroup("DefaultOptions"); - - char ** array = libhal_device_get_property_strlist(m_halContext, volume_udi.latin1(), "volume.mount.valid_options", NULL); - TQMap<TQString,bool> valids; - - for (int index = 0; array && array[index]; ++index) { - TQString t = array[index]; - if (t.endsWith("=")) - t = t.left(t.length() - 1); - valids[t] = true; - kdDebug() << "valid " << t << endl; - } - libhal_free_string_array(array); - TQStringList result; - TQString tmp; - - result << TQString("use_defaults=%1").arg(use_defaults ? "true" : "false"); - - TQString fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.fstype"); - if (fstype.isNull()) - fstype = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.mount_filesystem"); - - TQString drive_udi = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "block.storage_device"); - - bool removable = false; - if ( !drive_udi.isNull() ) - removable = libhal_device_get_property_bool(m_halContext, drive_udi.latin1(), "storage.removable", NULL) - || libhal_device_get_property_bool(m_halContext, drive_udi.latin1(), "storage.hotpluggable", NULL); - - bool value; - if (use_defaults) - { - value = config.readBoolEntry("automount", false); - } - else - { - QString current_group = config.group(); - config.setGroup(drive_udi); - value = config.readBoolEntry("automount", false); - config.setGroup(current_group); - } - - if (libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_blank", NULL) - || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_vcd", NULL) - || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_svcd", NULL) - || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.is_videodvd", NULL) - || libhal_device_get_property_bool(m_halContext, volume_udi.latin1(), "volume.disc.has_audio", NULL)) - value = false; - - result << TQString("automount=%1").arg(value ? "true" : "false"); - - if (valids.contains("ro")) - { - value = config.readBoolEntry("ro", false); - tmp = TQString("ro=%1").arg(value ? "true" : "false"); - if (fstype != "iso9660") // makes no sense - result << tmp; - } - - if (valids.contains("quiet")) - { - value = config.readBoolEntry("quiet", false); - tmp = TQString("quiet=%1").arg(value ? "true" : "false"); - if (fstype != "iso9660") // makes no sense - result << tmp; - } - - if (valids.contains("flush")) - { - value = config.readBoolEntry("flush", fstype.endsWith("fat")); - tmp = TQString("flush=%1").arg(value ? "true" : "false"); - result << tmp; - } - - if (valids.contains("uid")) - { - value = config.readBoolEntry("uid", true); - tmp = TQString("uid=%1").arg(value ? "true" : "false"); - result << tmp; - } - - if (valids.contains("utf8")) - { - value = config.readBoolEntry("utf8", true); - tmp = TQString("utf8=%1").arg(value ? "true" : "false"); - result << tmp; - } - - if (valids.contains("shortname")) - { - TQString svalue = config.readEntry("shortname", "lower").lower(); - if (svalue == "windows nt") - result << "shortname=winnt"; - else if (svalue == "windows 95") - result << "shortname=win95"; - else if (svalue == "mixed") - result << "shortname=mixed"; - else - result << "shortname=lower"; - } - - // pass our locale to the ntfs-3g driver so it can translate local characters - if (valids.contains("locale") && fstype == "ntfs-3g") - { - // have to obtain LC_CTYPE as returned by the `locale` command - // check in the same order as `locale` does - char *cType; - if ( (cType = getenv("LC_ALL")) || (cType = getenv("LC_CTYPE")) || (cType = getenv("LANG")) ) { - result << TQString("locale=%1").arg(cType); - } - } - - if (valids.contains("sync")) - { - value = config.readBoolEntry("sync", ( valids.contains("flush") && !fstype.endsWith("fat") ) && removable); - tmp = TQString("sync=%1").arg(value ? "true" : "false"); - if (fstype != "iso9660") // makes no sense - result << tmp; - } - - if (valids.contains("noatime")) - { - value = config.readBoolEntry("atime", !fstype.endsWith("fat")); - tmp = TQString("atime=%1").arg(value ? "true" : "false"); - if (fstype != "iso9660") // makes no sense - result << tmp; - } - - TQString mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.mount_point"); - if (mount_point.isEmpty()) - mount_point = libhal_device_get_property_QString(m_halContext, volume_udi.latin1(), "volume.policy.desired_mount_point"); - - mount_point = config.readEntry("mountpoint", mount_point); - - if (!mount_point.startsWith("/")) - mount_point = "/media/" + mount_point; - - result << TQString("mountpoint=%1").arg(mount_point); - result << TQString("filesystem=%1").arg(fstype); - - if (valids.contains("data")) - { - TQString svalue = config.readEntry("journaling").lower(); - if (svalue == "ordered") - result << "journaling=ordered"; - else if (svalue == "writeback") - result << "journaling=writeback"; - else if (svalue == "data") - result << "journaling=data"; - else - result << "journaling=ordered"; - } - - return result; -} - -bool HALBackend::setMountoptions(const TQString &name, const TQStringList &options ) -{ - kdDebug() << "setMountoptions " << name << " " << options << endl; - - TDEConfig config("mediamanagerrc"); - config.setGroup(name); - - TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(options); - - const char *names[] = { "use_defaults", "ro", "quiet", "atime", "uid", "utf8", "flush", "sync", 0 }; - for (int index = 0; names[index]; ++index) - if (valids.contains(names[index])) - config.writeEntry(names[index], valids[names[index]] == "true"); - - if (valids.contains("shortname")) - config.writeEntry("shortname", valids["shortname"]); - - if (valids.contains("journaling")) - config.writeEntry("journaling", valids["journaling"]); - - if (!mountoptions(name).contains(TQString("mountpoint=%1").arg(valids["mountpoint"]))) - config.writeEntry("mountpoint", valids["mountpoint"]); - - if (valids.contains("automount")) { - TQString drive_udi = libhal_device_get_property_QString(m_halContext, name.latin1(), "block.storage_device"); - config.setGroup(drive_udi); - config.writeEntry("automount", valids["automount"]); - } - - return true; -} - -TQString startKdeSudoProcess(const TQString& tdesudoPath, const TQString& command, - const TQString& dialogCaption, const TQString& dialogComment) -{ - TDEProcess tdesudoProcess; - - tdesudoProcess << tdesudoPath - << "-d" - << "--noignorebutton" - << "--caption" << dialogCaption - << "--comment" << dialogComment - << "-c" << command; - - // @todo handle tdesudo output - tdesudoProcess.start(TDEProcess::Block); - - return TQString(); -} - -TQString startKdeSuProcess(const TQString& tdesuPath, const TQString& command, - const TQString& dialogCaption) -{ - TDEProcess tdesuProcess; - - tdesuProcess << tdesuPath - << "-d" - << "--noignorebutton" - << "--caption" << dialogCaption - << "-c" << command; - - // @todo handle tdesu output - tdesuProcess.start(TDEProcess::Block); - - return TQString(); -} - -TQString startPrivilegedProcess(const TQString& command, const TQString& dialogCaption, const TQString& dialogComment) -{ - TQString error; - - TQString tdesudoPath = TDEStandardDirs::findExe("tdesudo"); - - if (!tdesudoPath.isEmpty()) - error = startKdeSudoProcess(tdesudoPath, command, dialogCaption, dialogComment); - else { - TQString tdesuPath = TDEStandardDirs::findExe("tdesu"); - - if (!tdesuPath.isEmpty()) - error = startKdeSuProcess(tdesuPath, command, dialogCaption); - } - - return error; -} - -TQString privilegedMount(const char* udi, const char* mountPoint, const char** options, int numberOfOptions) -{ - TQString error; - - kdDebug() << "run privileged mount for " << udi << endl; - - TQString dbusSendPath = TDEStandardDirs::findExe("dbus-send"); - - // @todo return error message - if (dbusSendPath.isEmpty()) - return TQString(); - - TQString mountOptions; - TQTextOStream optionsStream(&mountOptions); - for (int optionIndex = 0; optionIndex < numberOfOptions; optionIndex++) { - optionsStream << options[optionIndex]; - if (optionIndex < numberOfOptions - 1) - optionsStream << ","; - } - - TQString command; - TQTextOStream(&command) << dbusSendPath - << " --system --print-reply --dest=org.freedesktop.Hal " << udi - << " org.freedesktop.Hal.Device.Volume.Mount string:" << mountPoint - << " string: array:string:" << mountOptions; - - kdDebug() << "command: " << command << endl; - - error = startPrivilegedProcess(command, - i18n("Authenticate"), - i18n("<big><b>System policy prevents mounting internal media</b></big><br/>Authentication is required to perform this action. Please enter your password to verify.")); - - return error; -} - -TQString privilegedUnmount(const char* udi) -{ - TQString error; - - kdDebug() << "run privileged unmount for " << udi << endl; - - TQString dbusSendPath = TDEStandardDirs::findExe("dbus-send"); - - // @todo return error message - if (dbusSendPath.isEmpty()) - return TQString(); - - TQString command; - TQTextOStream(&command) << dbusSendPath - << " --system --print-reply --dest=org.freedesktop.Hal " << udi - << " org.freedesktop.Hal.Device.Volume.Unmount array:string:force"; - - kdDebug() << "command: " << command << endl; - - error = startPrivilegedProcess(command, - i18n("Authenticate"), - i18n("<big><b>System policy prevents unmounting media mounted by other users</b></big><br/>Authentication is required to perform this action. Please enter your password to verify.")); - - return error; -} - -static TQString mount_priv(const char *udi, const char *mount_point, const char **poptions, int noptions, - DBusConnection *dbus_connection) -{ - DBusMessage *dmesg, *reply; - DBusError error; - - const char *fstype = ""; - if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, - "org.freedesktop.Hal.Device.Volume", - "Mount"))) { - kdDebug() << "mount failed for " << udi << ": could not create dbus message\n"; - return i18n("Internal Error"); - } - - if (!dbus_message_append_args (dmesg, DBUS_TYPE_STRING, &mount_point, DBUS_TYPE_STRING, &fstype, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &poptions, noptions, - DBUS_TYPE_INVALID)) - { - kdDebug() << "mount failed for " << udi << ": could not append args to dbus message\n"; - dbus_message_unref (dmesg); - return i18n("Internal Error"); - } - - TQString qerror; - - dbus_error_init (&error); - if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, dmesg, -1, &error))) - { - TQString qerror = error.message; - kdError() << "mount failed for " << udi << ": " << error.name << " - " << qerror << endl; - if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.UnknownFilesystemType")) - qerror = i18n("Invalid filesystem type"); - else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied")) - qerror = i18n("Permission denied<p>Please ensure that:<br>1. You have permission to access this device.<br>2. This device node is not listed in /etc/fstab.</p>"); - else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) - qerror = privilegedMount(udi, mount_point, poptions, noptions); - else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.AlreadyMounted")) - qerror = i18n("Device is already mounted."); - else if ( !strcmp(error.name, "org.freedesktop.Hal.Device.Volume.InvalidMountpoint") && strlen(mount_point)) { - dbus_message_unref (dmesg); - dbus_error_free (&error); - return mount_priv(udi, "", poptions, noptions, dbus_connection); - } - dbus_message_unref (dmesg); - dbus_error_free (&error); - return qerror; - } - - kdDebug() << "mount queued for " << udi << endl; - - dbus_message_unref (dmesg); - dbus_message_unref (reply); - - return qerror; - -} - -TQString HALBackend::listUsingProcesses(const Medium* medium) -{ - TQString proclist, fullmsg; - TQString fuserpath = TDEStandardDirs::findExe("fuser", TQString("/sbin:/usr/sbin:") + getenv( "PATH" )); - FILE *fuser = NULL; - - uint counter = 0; - if (!fuserpath.isEmpty()) { - TQString cmdline = TQString("/usr/bin/env %1 -vm %2 2>&1").arg(fuserpath, TDEProcess::quote(medium->mountPoint())); - fuser = popen(cmdline.latin1(), "r"); - } - if (fuser) { - proclist += "<pre>"; - TQTextIStream is(fuser); - TQString tmp; - while (!is.atEnd()) { - tmp = is.readLine(); - tmp = TQStyleSheet::escape(tmp) + "\n"; - - proclist += tmp; - if (counter++ > 10) - { - proclist += "..."; - break; - } - } - proclist += "</pre>"; - (void)pclose( fuser ); - } - if (counter) { - fullmsg = i18n("Moreover, programs still using the device " - "have been detected. They are listed below. You have to " - "close them or change their working directory before " - "attempting to unmount the device again."); - fullmsg += "<br>" + proclist; - return fullmsg; - } else { - return TQString::null; - } -} - -TQString HALBackend::killUsingProcesses(const Medium* medium) -{ - TQString proclist, fullmsg; - TQString fuserpath = TDEStandardDirs::findExe("fuser", TQString("/sbin:/usr/sbin:") + getenv( "PATH" )); - FILE *fuser = NULL; - - uint counter = 0; - if (!fuserpath.isEmpty()) { - TQString cmdline = TQString("/usr/bin/env %1 -vmk %2 2>&1").arg(fuserpath, TDEProcess::quote(medium->mountPoint())); - fuser = popen(cmdline.latin1(), "r"); - } - if (fuser) { - proclist += "<pre>"; - TQTextIStream is(fuser); - TQString tmp; - while (!is.atEnd()) { - tmp = is.readLine(); - tmp = TQStyleSheet::escape(tmp) + "\n"; - - proclist += tmp; - if (counter++ > 10) - { - proclist += "..."; - break; - } - } - proclist += "</pre>"; - (void)pclose( fuser ); - } - if (counter) { - fullmsg = i18n("Programs that were still using the device " - "have been forcibly terminated. They are listed below."); - fullmsg += "<br>" + proclist; - return fullmsg; - } else { - return TQString::null; - } -} - -void HALBackend::slotResult(TDEIO::Job *job) -{ - kdDebug() << "slotResult " << mount_jobs[job] << endl; - - struct mount_job_data *data = mount_jobs[job]; - TQString& qerror = data->errorMessage; - const Medium* medium = data->medium; - - if (job->error() == TDEIO::ERR_COULD_NOT_UNMOUNT) { - TQString proclist(listUsingProcesses(medium)); - - qerror = "<qt>"; - qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and " - "currently mounted at <b>%4</b> could not be unmounted. ").arg( - "system:/media/" + medium->name(), - medium->deviceNode(), - medium->prettyLabel(), - medium->prettyBaseURL().pathOrURL()) + "</p>"; - qerror += "<p>" + i18n("The following error was returned by umount command:"); - qerror += "</p><pre>" + job->errorText() + "</pre>"; - - if (!proclist.isEmpty()) { - qerror += proclist; - } - qerror += "</qt>"; - } else if (job->error()) { - qerror = job->errorText(); - } - - ResetProperties( medium->id().latin1() ); - mount_jobs.remove(job); - - /* Job completed. Notify the caller */ - data->error = job->error(); - data->completed = true; - kapp->eventLoop()->exitLoop(); -} - -TQString HALBackend::isInFstab(const Medium *medium) -{ - KMountPoint::List fstab = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions|KMountPoint::NeedRealDeviceName); - - KMountPoint::List::iterator it = fstab.begin(); - KMountPoint::List::iterator end = fstab.end(); - - for (; it!=end; ++it) - { - TQString reald = (*it)->realDeviceName(); - if ( reald.endsWith( "/" ) ) - reald = reald.left( reald.length() - 1 ); - kdDebug() << "isInFstab -" << medium->deviceNode() << "- -" << reald << "- -" << (*it)->mountedFrom() << "-" << endl; - if ((*it)->mountedFrom() == medium->deviceNode() || ( !medium->deviceNode().isEmpty() && reald == medium->deviceNode() ) ) - { - TQStringList opts = (*it)->mountOptions(); - if (opts.contains("user") || opts.contains("users")) - return (*it)->mountPoint(); - } - } - - return TQString::null; -} - -TQStringVariantMap HALBackend::mount(const Medium *medium) -{ - TQStringVariantMap result; - if (medium->isMounted()) { - result["result"] = true; - return result; - } - - TQString mountPoint = isInFstab(medium); - if (!mountPoint.isNull()) - { - struct mount_job_data data; - data.completed = false; - data.medium = medium; - - kdDebug() << "triggering user mount " << medium->deviceNode() << " " << mountPoint << " " << medium->id() << endl; - TDEIO::Job *job = TDEIO::mount( false, 0, medium->deviceNode(), mountPoint ); - connect(job, TQT_SIGNAL(result(TDEIO::Job*)), TQT_SLOT(slotResult(TDEIO::Job*))); - mount_jobs[job] = &data; - // The caller expects the device to be mounted when the function - // completes. Thus block until the job completes. - while (!data.completed) { - kapp->eventLoop()->enterLoop(); - } - if (!data.error) { - result["result"] = true; - return result; - } - else { - result["errStr"] = data.errorMessage; // Return the error message (if any) to the caller - result["result"] = false; - return result; - } - } - - kdDebug() << "mounting " << medium->id() << "..." << endl; - - TQStringList soptions; - TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(mountoptions(medium->id())); - if (valids["flush"] == "true") - soptions << "flush"; - - if ((valids["uid"] == "true") && (medium->fsType() != "ntfs")) - { - soptions << TQString("uid=%1").arg(getuid()); - } - - if (valids["ro"] == "true") - soptions << "ro"; - - if (valids["atime"] != "true") - soptions << "noatime"; - - if (valids["quiet"] == "true") - soptions << "quiet"; - - if (valids["utf8"] == "true") - soptions << "utf8"; - - if (valids["sync"] == "true") - soptions << "sync"; - - if (medium->fsType() == "ntfs") { - TQString fsLocale("locale="); - fsLocale += setlocale(LC_ALL, ""); - soptions << fsLocale; - } - - TQString mount_point = valids["mountpoint"]; - if (mount_point.startsWith("/media/")) - mount_point = mount_point.mid(7); - - if (valids.contains("shortname")) - { - soptions << TQString("shortname=%1").arg(valids["shortname"]); - } - - if (valids.contains("locale")) - { - soptions << TQString("locale=%1").arg(valids["locale"]); - } - - if (valids.contains("journaling")) - { - TQString option = valids["journaling"]; - if (option == "data") - soptions << TQString("data=journal"); - else if (option == "writeback") - soptions << TQString("data=writeback"); - else - soptions << TQString("data=ordered"); - } - - TQStringList hal_mount_options = getHALmountoptions(medium->id()); - for (TQValueListIterator<TQString> it=hal_mount_options.begin();it!=hal_mount_options.end();it++) - { - soptions << *it; - kdDebug()<<"HALOption: "<<*it<<endl; - if ((*it).startsWith("iocharset=")) - { - soptions.remove("utf8"); - kdDebug()<<"\"iocharset=\" found. Removing \"utf8\" from options."<<endl; - } - } - - const char **options = new const char*[soptions.size() + 1]; - uint noptions = 0; - for (TQStringList::ConstIterator it = soptions.begin(); it != soptions.end(); ++it, ++noptions) - { - options[noptions] = (*it).latin1(); - kdDebug()<<"Option: "<<*it<<endl; - } - options[noptions] = NULL; - - TQString qerror; - if (!medium->isEncrypted()) { - // normal volume - qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection); - } else { - // see if we have a clear volume - error = i18n("Cannot mount encrypted locked drives!"); - LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); - if (halVolume) { - char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); - if (clearUdi != NULL) { - qerror = mount_priv(clearUdi, mount_point.utf8(), options, noptions, dbus_connection); - libhal_free_string(clearUdi); - } - libhal_volume_free(halVolume); - } - } - - if (!qerror.isEmpty()) { - kdError() << "mounting " << medium->id() << " returned " << qerror << endl; - result["errStr"] = qerror; - result["result"] = false; - return result; - } - - medium->setHalMounted(true); - ResetProperties(medium->id().latin1()); - - result["result"] = true; - return result; -} - -TQStringVariantMap HALBackend::mount(const TQString &id) -{ - const Medium *medium = m_mediaList.findById(id); - if (!medium) { - TQStringVariantMap result; - result["errStr"] = i18n("No such medium: %1").arg(id); - result["result"] = false; - return result; - } - return mount(medium); -} - -TQStringVariantMap HALBackend::unmount(const TQString &id) -{ - TQStringVariantMap result; - - const Medium* medium = m_mediaList.findById(id); - if (!medium) - { - // now we get fancy: if the udi is no volume, it _might_ be a device with only one - // volume on it (think CDs) - so we're so nice to the caller to unmount that volume - LibHalDrive* halDrive = libhal_drive_from_udi(m_halContext, id.latin1()); - if (halDrive) - { - int numVolumes; - char** volumes = libhal_drive_find_all_volumes(m_halContext, halDrive, &numVolumes); - if (numVolumes == 1) - medium = m_mediaList.findById(volumes[0]); - } - } - - if (!medium) { - result["errStr"] = i18n("No such medium: %1").arg(id); - result["result"] = false; - return result; - } - - if (!medium->isMounted()) { - result["result"] = true; - return result; - } - - TQString mountPoint = isInFstab(medium); - if (!mountPoint.isNull()) - { - struct mount_job_data data; - data.completed = false; - data.medium = medium; - - kdDebug() << "triggering user unmount " << medium->deviceNode() << " " << mountPoint << endl; - TDEIO::Job *job = TDEIO::unmount( medium->mountPoint(), false ); - connect(job, TQT_SIGNAL(result(TDEIO::Job*)), TQT_SLOT(slotResult(TDEIO::Job*))); - mount_jobs[job] = &data; - // The caller expects the device to be unmounted when the function - // completes. Thus block until the job completes. - while (!data.completed) { - kapp->eventLoop()->enterLoop(); - } - if (!data.error) { - result["result"] = true; - return result; - } - else { - result["errStr"] = data.errorMessage; // Return the error message (if any) to the caller - result["result"] = false; - return result; - } - } - - DBusMessage *dmesg, *reply; - DBusError error; - const char *options[2]; - TQString udi = TQString::null; - - if (!medium->isEncrypted()) { - // normal volume - udi = medium->id(); - } else { - // see if we have a clear volume - LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1()); - if (halVolume) { - char *clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume); - udi = clearUdi; - libhal_free_string(clearUdi); - libhal_volume_free(halVolume); - } - } - if (udi.isNull()) { - kdDebug() << "unmount failed: no udi" << endl; - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - kdDebug() << "unmounting " << udi << "..." << endl; - - dbus_error_init(&error); - DBusConnection *dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (dbus_error_is_set(&error)) - { - dbus_error_free(&error); - result["errStr"] = i18n("Unknown error"); - result["result"] = false; - return result; - } - - if (!(dmesg = dbus_message_new_method_call ("org.freedesktop.Hal", udi.latin1(), - "org.freedesktop.Hal.Device.Volume", - "Unmount"))) { - kdDebug() << "unmount failed for " << udi << ": could not create dbus message\n"; - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - options[0] = "force"; - options[1] = 0; - - if (!dbus_message_append_args (dmesg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, 0, - DBUS_TYPE_INVALID)) - { - kdDebug() << "unmount failed for " << udi << ": could not append args to dbus message\n"; - dbus_message_unref (dmesg); - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - char thisunmounthasfailed = 0; - dbus_error_init (&error); - if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, dmesg, -1, &error))) - { - thisunmounthasfailed = 1; - TQString qerror, reason, origqerror; - - if (!strcmp(error.name, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy")) { - qerror = privilegedUnmount(udi.latin1()); - - if (qerror.isEmpty()) { - dbus_message_unref(dmesg); - dbus_error_free(&error); - result["result"] = true; - return result; - } - - // @todo handle unmount error message - } - - kdDebug() << "unmount failed for " << udi << ": " << error.name << " " << error.message << endl; - qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and " - "currently mounted at <b>%4</b> could not be unmounted. ").arg( - "system:/media/" + medium->name(), - medium->deviceNode(), - medium->prettyLabel(), - medium->prettyBaseURL().pathOrURL()) + "</p>"; - qerror += "<p>" + i18n("Unmounting failed due to the following error:") + "</p>"; - if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.Busy")) { - reason = i18n("Device is Busy:"); - thisunmounthasfailed = 2; - } else if (!strcmp(error.name, "org.freedesktop.Hal.Device.Volume.NotMounted")) { - // this is faking. The error is that the device wasn't mounted by hal (but by the system) - reason = i18n("Permission denied<p>Please ensure that:<br>1. You have permission to access this device.<br>2. This device was originally mounted using TDE.</p>"); - } else { - reason = error.message; - } - qerror += "<p><b>" + reason + "</b></p>"; - origqerror = qerror; - - // Include list of processes (if any) using the device in the error message - reason = listUsingProcesses(medium); - if (!reason.isEmpty()) { - qerror += reason; - if (thisunmounthasfailed == 2) { // Failed as BUSY - if (KMessageBox::warningYesNo(0, i18n("%1<p><b>Would you like to forcibly terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg(qerror)) == KMessageBox::Yes) { - qerror = origqerror; - reason = killUsingProcesses(medium); - qerror = HALBackend::unmount(udi); - if (qerror.isNull()) { - thisunmounthasfailed = 0; - } - } - } - } - - if (thisunmounthasfailed != 0) { - dbus_message_unref (dmesg); - dbus_error_free (&error); - result["errStr"] = qerror; - result["result"] = false; - return result; - } - } - - kdDebug() << "unmount queued for " << udi << endl; - - dbus_message_unref (dmesg); - if (reply) { - dbus_message_unref (reply); - } - - medium->setHalMounted(false); - ResetProperties(medium->id().latin1()); - - while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; - - result["result"] = true; - return result; -} - -TQStringVariantMap HALBackend::unlock(const TQString &id, const TQString &password) -{ - TQStringVariantMap result; - - const Medium *medium = m_mediaList.findById(id); - if (!medium) { - result["errStr"] = i18n("No such medium: %1").arg(id); - result["result"] = false; - return result; - } - - if (!medium->isEncrypted() || !medium->clearDeviceUdi().isNull()) { - result["result"] = true; - return result; - } - - const char *udi = medium->id().latin1(); - DBusMessage *msg = NULL; - DBusMessage *reply = NULL; - DBusError error; - - kdDebug() << "Setting up " << udi << " for crypto\n" <<endl; - - msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, - "org.freedesktop.Hal.Device.Volume.Crypto", - "Setup"); - if (msg == NULL) { - kdDebug() << "unlock failed for " << udi << ": could not create dbus message\n"; - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - TQCString pwdUtf8 = password.utf8(); - const char *pwd_utf8 = pwdUtf8; - if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &pwd_utf8, DBUS_TYPE_INVALID)) { - kdDebug() << "unlock failed for " << udi << ": could not append args to dbus message\n"; - dbus_message_unref (msg); - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - dbus_error_init (&error); - if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) || - dbus_error_is_set (&error)) - { - TQString qerror = i18n("Internal Error"); - kdDebug() << "unlock failed for " << udi << ": " << error.name << " " << error.message << endl; - if (strcmp (error.name, "org.freedesktop.Hal.Device.Volume.Crypto.SetupPasswordError") == 0) { - qerror = i18n("Wrong password"); - } - dbus_error_free (&error); - dbus_message_unref (msg); - while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; - result["errStr"] = qerror; - result["result"] = false; - return result; - } - - dbus_message_unref (msg); - dbus_message_unref (reply); - - while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; - - result["result"] = true; - return result; -} - -TQStringVariantMap HALBackend::lock(const TQString &id) -{ - TQStringVariantMap result; - - const Medium *medium = m_mediaList.findById(id); - if (!medium) { - result["errStr"] = i18n("No such medium: %1").arg(id); - result["result"] = false; - return result; - } - - if (!medium->isEncrypted() || !medium->clearDeviceUdi().isNull()) { - result["result"] = true; - return result; - } - - const char *udi = medium->id().latin1(); - DBusMessage *msg = NULL; - DBusMessage *reply = NULL; - DBusError error; - - kdDebug() << "Tear down " << udi << "\n" <<endl; - - msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi, - "org.freedesktop.Hal.Device.Volume.Crypto", - "Teardown"); - if (msg == NULL) { - kdDebug() << "lock failed for " << udi << ": could not create dbus message\n"; - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - if (!dbus_message_append_args (msg, DBUS_TYPE_INVALID)) { - kdDebug() << "lock failed for " << udi << ": could not append args to dbus message\n"; - dbus_message_unref (msg); - result["errStr"] = i18n("Internal error"); - result["result"] = false; - return result; - } - - dbus_error_init (&error); - if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error)) || - dbus_error_is_set (&error)) - { - TQString qerror = i18n("Internal Error"); - kdDebug() << "lock failed for " << udi << ": " << error.name << " " << error.message << endl; - dbus_error_free (&error); - dbus_message_unref (msg); - while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; - result["errStr"] = qerror; - result["result"] = false; - return result; - } - - dbus_message_unref (msg); - dbus_message_unref (reply); - - ResetProperties(udi); - - while (dbus_connection_dispatch(dbus_connection) == DBUS_DISPATCH_DATA_REMAINS) ; - - result["result"] = true; - return result; -} - -#include "halbackend.moc" diff --git a/tdeioslave/media/mediamanager/halbackend.h b/tdeioslave/media/mediamanager/halbackend.h deleted file mode 100644 index ed512fa7b..000000000 --- a/tdeioslave/media/mediamanager/halbackend.h +++ /dev/null @@ -1,233 +0,0 @@ -/* This file is part of the KDE Project - Copyright (c) 2004-2005 Jérôme Lodewyck <jerome dot lodewyck at normalesup dot org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** -* This is a media:/ backend for the freedesktop Hardware Abstraction Layer -* Usage : create an instance of HALBackend, then call InitHal(). A false -* result from the later function means that something went wrong and that -* the backend shall not be used. -* -* @author Jérôme Lodewyck <jerome dot lodewyck at normalesup dot org> -* @short media:/ backend for the HAL -*/ - -#ifndef _HALBACKEND_H_ -#define _HALBACKEND_H_ - -#include "backendbase.h" - -#include <tqobject.h> -#include <tqstringlist.h> -#include <tqstring.h> -#include <tqregexp.h> - -#include <config.h> - -/* We acknowledge the the dbus API is unstable */ -#define DBUS_API_SUBJECT_TO_CHANGE -/* DBus-Qt bindings */ -#include <dbus/connection.h> -/* HAL libraries */ -#include <libhal.h> -#include <libhal-storage.h> - -namespace TDEIO { - class Job; -} - -class HALBackend : public TQObject, public BackendBase -{ -Q_OBJECT - -public: - /** - * Constructor - */ - HALBackend(MediaList &list, TQObject* parent); - - /** - * Destructor - */ - ~HALBackend(); - - /** - * Perform HAL initialization. - * - * @return true if succeded. If not, rely on some other backend - */ - bool InitHal(); - - /** - * List all devices and append them to the media device list (called only once, at startup). - * - * @return true if succeded, false otherwise - */ - bool ListDevices(); - - TQStringList mountoptions(const TQString &id); - - bool setMountoptions(const TQString &id, const TQStringList &options); - - TQStringVariantMap mount(const TQString &id); - TQStringVariantMap mount(const Medium *medium); - TQStringVariantMap unmount(const TQString &id); - TQStringVariantMap unlock(const TQString &id, const TQString &password); - TQStringVariantMap lock(const TQString &id); - -private: - /** - * Append a device in the media list. This function will check if the device - * is worth listing. - * - * @param udi Universal Device Id - * @param allowNotification Indicates if this event will be notified to the user - */ - void AddDevice(const char* udi, bool allowNotification=true); - - /** - * Remove a device from the device list - * - * @param udi Universal Device Id - */ - void RemoveDevice(const char* udi); - - /** - * A device has changed, update it - * - * @param udi Universal Device Id - */ - void ModifyDevice(const char *udi, const char* key); - - /** - * HAL informed that a special action has occured - * (e.g. device unplugged without unmounting) - * - * @param udi Universal Device Id - */ - void DeviceCondition(const char *udi, const char *condition); - - /** - * Integrate the DBus connection within qt main loop - */ - void MainLoopIntegration(DBusConnection *dbusConnection); - -/* Set media properties */ -private: - /** - * Reset properties for the given medium - */ - void ResetProperties(const char* MediumUdi, bool allowNotification=false); - - /** - * Find the medium that is concerned with device udi - */ - const char* findMediumUdiFromUdi(const char* udi); - - void setVolumeProperties(Medium* medium); - bool setFloppyProperties(Medium* medium); - void setFloppyMountState( Medium* medium ); - bool setFstabProperties(Medium* medium); - void setCameraProperties(Medium* medium); - TQString generateName(const TQString &devNode); - static TQString isInFstab(const Medium *medium); - static TQString listUsingProcesses(const Medium *medium); - static TQString killUsingProcesses(const Medium *medium); - -private slots: - void slotResult(TDEIO::Job *job); - -/* Hal call-backs -- from gvm*/ -public: - /** Invoked when a device is added to the Global Device List. - * - * @param ctx LibHal context - * @param udi Universal Device Id - */ - static void hal_device_added(LibHalContext *ctx, const char *udi); - - /** Invoked when a device is removed from the Global Device List. - * - * @param ctx LibHal context - * @param udi Universal Device Id - */ - static void hal_device_removed(LibHalContext *ctx, const char *udi); - - /** Invoked when a property of a device in the Global Device List is - * changed, and we have we have subscribed to changes for that device. - * - * @param ctx LibHal context - * @param udi Univerisal Device Id - * @param key Key of property - */ - static void hal_device_property_modified(LibHalContext *ctx, const char *udi, const char *key, - dbus_bool_t is_removed, dbus_bool_t is_added); - - /** Type for callback when a non-continuos condition occurs on a device - * - * @param udi Univerisal Device Id - * @param condition_name Name of the condition - * @param message D-BUS message with variable parameters depending on condition - */ - static void hal_device_condition(LibHalContext *ctx, const char *udi, - const char *condition_name, - const char* message - ); - - TQStringList getHALmountoptions(TQString udi); -/* HAL and DBus structures */ -private: - /** - * The HAL context connecting the whole application to the HAL - */ - LibHalContext* m_halContext; - - /** - * libhal-storage HAL policy, e.g. for icon names - */ - LibHalStoragePolicy* m_halStoragePolicy; - - /** - * The DBus-Qt bindings connection for mainloop integration - */ - DBusQt::Connection* m_dBusQtConnection; - - /** - * Object for the kded module - */ - TQObject* m_parent; - - DBusConnection *dbus_connection; - - /** - * Data structure for fstab mount/unmount jobs - */ - struct mount_job_data { - // [in] Medium, which is being mounted/unmounted by the job - const Medium* medium; - // [in,out] Should be set to true when the job completes - bool completed; - // [out] TDEIO::Error if an error occured during operation. Otherwise, 0 - int error; - // [out] Error message to be displayed to the user - TQString errorMessage; - }; - - TQMap<TDEIO::Job *, struct mount_job_data*> mount_jobs; -}; - -#endif /* _HALBACKEND_H_ */ diff --git a/tdeioslave/media/mediamanager/linuxcdpolling.cpp b/tdeioslave/media/mediamanager/linuxcdpolling.cpp index eccdf1f34..66074f40e 100644 --- a/tdeioslave/media/mediamanager/linuxcdpolling.cpp +++ b/tdeioslave/media/mediamanager/linuxcdpolling.cpp @@ -176,19 +176,19 @@ private: LinuxCDPolling::LinuxCDPolling(MediaList &list) : TQObject(), BackendBase(list) { - connect(&m_mediaList, TQT_SIGNAL(mediumAdded(const TQString &, + connect(&m_mediaList, TQ_SIGNAL(mediumAdded(const TQString &, const TQString &, bool)), - this, TQT_SLOT(slotMediumAdded(const TQString &)) ); + this, TQ_SLOT(slotMediumAdded(const TQString &)) ); - connect(&m_mediaList, TQT_SIGNAL(mediumRemoved(const TQString &, + connect(&m_mediaList, TQ_SIGNAL(mediumRemoved(const TQString &, const TQString &, bool)), - this, TQT_SLOT(slotMediumRemoved(const TQString &)) ); + this, TQ_SLOT(slotMediumRemoved(const TQString &)) ); - connect(&m_mediaList, TQT_SIGNAL(mediumStateChanged(const TQString &, + connect(&m_mediaList, TQ_SIGNAL(mediumStateChanged(const TQString &, const TQString &, bool, bool)), - this, TQT_SLOT(slotMediumStateChanged(const TQString &)) ); + this, TQ_SLOT(slotMediumStateChanged(const TQString &)) ); - connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout())); + connect(&m_timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotTimeout())); } LinuxCDPolling::~LinuxCDPolling() @@ -514,7 +514,7 @@ bool LinuxCDPolling::hasDirectory(const TQCString &devNode, const TQCString &dir close(fd); return false; } - if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + if (TQ_BYTE_ORDER != TQ_LITTLE_ENDIAN) bs = ((bs << 8) & 0xFF00) | ((bs >> 8) & 0xFF); // read in size of path table @@ -524,7 +524,7 @@ bool LinuxCDPolling::hasDirectory(const TQCString &devNode, const TQCString &dir close(fd); return false; } - if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + if (TQ_BYTE_ORDER != TQ_LITTLE_ENDIAN) ts = ((ts << 8) & 0xFF00) | ((ts >> 8) & 0xFF); // read in which block path table is in @@ -534,7 +534,7 @@ bool LinuxCDPolling::hasDirectory(const TQCString &devNode, const TQCString &dir close(fd); return false; } - if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + if (TQ_BYTE_ORDER != TQ_LITTLE_ENDIAN) tl = ((tl << 24) & 0xFF000000) | ((tl << 8) & 0xFF0000) | ((tl >> 8) & 0xFF00) | ((tl >> 24) & 0xFF); @@ -559,7 +559,7 @@ bool LinuxCDPolling::hasDirectory(const TQCString &devNode, const TQCString &dir ret = false; break; } - if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN) + if (TQ_BYTE_ORDER != TQ_LITTLE_ENDIAN) parent = ((parent << 8) & 0xFF00) | ((parent >> 8) & 0xFF); // read the name diff --git a/tdeioslave/media/mediamanager/linuxcdpolling.h b/tdeioslave/media/mediamanager/linuxcdpolling.h index fc4947470..070ad5eea 100644 --- a/tdeioslave/media/mediamanager/linuxcdpolling.h +++ b/tdeioslave/media/mediamanager/linuxcdpolling.h @@ -49,7 +49,7 @@ class PollingThread; class LinuxCDPolling : public TQObject, public BackendBase { -Q_OBJECT +TQ_OBJECT public: diff --git a/tdeioslave/media/mediamanager/medialist.cpp b/tdeioslave/media/mediamanager/medialist.cpp index b06824d0c..8ea9aec50 100644 --- a/tdeioslave/media/mediamanager/medialist.cpp +++ b/tdeioslave/media/mediamanager/medialist.cpp @@ -128,42 +128,43 @@ bool MediaList::changeMediumState(const Medium &medium, bool allowNotification) { kdDebug(1219) << "MediaList::changeMediumState(const Medium &) for id " << medium.id() << endl; - if ( !m_idMap.contains(medium.id()) ) return false; + if (!m_idMap.contains(medium.id())) return false; Medium *m = m_idMap[medium.id()]; - if ( medium.isMountable() ) + m->setEncrypted(medium.isEncrypted()); + m->setLocked(medium.isLocked()); + m->setMountable(medium.isMountable()); + if (medium.isMountable()) { - TQString device_node = medium.deviceNode(); - TQString clear_device_udi = medium.clearDeviceUdi(); - TQString mount_point = medium.mountPoint(); - TQString fs_type = medium.fsType(); - bool mounted = medium.isMounted(); - - m->mountableState( device_node, clear_device_udi, mount_point, fs_type, mounted ); + m->setDeviceNode(medium.deviceNode()); + m->setClearDeviceUdi(medium.clearDeviceUdi()); + m->setMountPoint(medium.mountPoint()); + m->setFsType(medium.fsType()); + m->setMounted(medium.isMounted()); } else { - m->unmountableState( medium.baseURL() ); + m->setBaseURL(medium.baseURL()); } - if (!medium.mimeType().isEmpty()) { - m->setMimeType( medium.mimeType() ); + m->setMimeType(medium.mimeType()); } if (!medium.iconName().isEmpty()) { - m->setIconName( medium.iconName() ); + m->setIconName(medium.iconName()); } if (!medium.label().isEmpty()) { - m->setLabel( medium.label() ); + m->setLabel(medium.label()); } m->setHidden(medium.hidden()); + m->setSoftHidden(medium.softHidden()); emit mediumStateChanged(m->id(), m->name(), !m->needMounting(), allowNotification); return true; @@ -184,7 +185,8 @@ bool MediaList::changeMediumState(const TQString &id, Medium *medium = m_idMap[id]; - medium->unmountableState( baseURL ); + medium->setMountable(false); + medium->setBaseURL(baseURL); if (!mimeType.isEmpty()) { @@ -225,7 +227,16 @@ bool MediaList::changeMediumState(const TQString &id, Medium *medium = m_idMap[id]; - medium->mountableState( deviceNode, mountPoint, fsType, mounted ); + if (medium->deviceNode().isEmpty() || !medium->isMountable()) + { + return false; + } + + medium->setMountable(true); + medium->setDeviceNode(deviceNode); + medium->setMountPoint(mountPoint); + medium->setFsType(fsType); + medium->setMounted(mounted); if (!mimeType.isEmpty()) { @@ -262,7 +273,12 @@ bool MediaList::changeMediumState(const TQString &id, bool mounted, Medium *medium = m_idMap[id]; - if ( !medium->mountableState( mounted ) ) return false; + if (medium->deviceNode().isEmpty() || !medium->isMountable()) + { + return false; + } + + medium->setMounted(mounted); if (!mimeType.isEmpty()) { diff --git a/tdeioslave/media/mediamanager/medialist.h b/tdeioslave/media/mediamanager/medialist.h index f4b088526..a92d1b6c0 100644 --- a/tdeioslave/media/mediamanager/medialist.h +++ b/tdeioslave/media/mediamanager/medialist.h @@ -23,9 +23,9 @@ #include "medium.h" -class MediaList : public QObject +class MediaList : public TQObject { -Q_OBJECT +TQ_OBJECT public: MediaList(); diff --git a/tdeioslave/media/mediamanager/mediamanager.cpp b/tdeioslave/media/mediamanager/mediamanager.cpp index 7a8262eec..66c456a24 100644 --- a/tdeioslave/media/mediamanager/mediamanager.cpp +++ b/tdeioslave/media/mediamanager/mediamanager.cpp @@ -36,10 +36,6 @@ #include "tdehardwarebackend.h" #endif // COMPILE_TDEHARDWAREBACKEND -#ifdef COMPILE_HALBACKEND -#include "halbackend.h" -#endif //COMPILE_HALBACKEND - #ifdef COMPILE_LINUXCDPOLLING #include "linuxcdpolling.h" #endif //COMPILE_LINUXCDPOLLING @@ -47,15 +43,15 @@ MediaManager::MediaManager(const TQCString &obj) : KDEDModule(obj), m_dirNotify(m_mediaList) { - connect( &m_mediaList, TQT_SIGNAL(mediumAdded(const TQString&, const TQString&, bool)), - TQT_SLOT(slotMediumAdded(const TQString&, const TQString&, bool)) ); - connect( &m_mediaList, TQT_SIGNAL(mediumRemoved(const TQString&, const TQString&, bool)), - TQT_SLOT(slotMediumRemoved(const TQString&, const TQString&, bool)) ); + connect( &m_mediaList, TQ_SIGNAL(mediumAdded(const TQString&, const TQString&, bool)), + TQ_SLOT(slotMediumAdded(const TQString&, const TQString&, bool)) ); + connect( &m_mediaList, TQ_SIGNAL(mediumRemoved(const TQString&, const TQString&, bool)), + TQ_SLOT(slotMediumRemoved(const TQString&, const TQString&, bool)) ); connect( &m_mediaList, - TQT_SIGNAL(mediumStateChanged(const TQString&, const TQString&, bool, bool)), - TQT_SLOT(slotMediumChanged(const TQString&, const TQString&, bool, bool)) ); + TQ_SIGNAL(mediumStateChanged(const TQString&, const TQString&, bool, bool)), + TQ_SLOT(slotMediumChanged(const TQString&, const TQString&, bool, bool)) ); - TQTimer::singleShot( 10, this, TQT_SLOT( loadBackends() ) ); + TQTimer::singleShot( 10, this, TQ_SLOT( loadBackends() ) ); } MediaManager::~MediaManager() @@ -80,33 +76,9 @@ void MediaManager::loadBackends() } mp_removableBackend = 0L; - m_halbackend = 0L; m_tdebackend = 0L; m_fstabbackend = 0L; -#ifdef COMPILE_HALBACKEND - if ( MediaManagerSettings::self()->halBackendEnabled() ) - { - m_mediaList.blockSignals(false); - m_halbackend = new HALBackend(m_mediaList, this); - if (m_halbackend->InitHal()) - { - m_backends.append( m_halbackend ); - m_fstabbackend = new FstabBackend(m_mediaList, true); - m_backends.append( m_fstabbackend ); - // No need to load something else... - m_mediaList.blockSignals(false); - return; - } - else - { - delete m_halbackend; - m_halbackend = 0; - m_mediaList.blockSignals(true); - } - } -#endif // COMPILE_HALBACKEND - #ifdef COMPILE_TDEHARDWAREBACKEND if ( MediaManagerSettings::self()->tdeHardwareBackendEnabled() ) { @@ -136,39 +108,22 @@ void MediaManager::loadBackends() m_mediaList.blockSignals(false); } - -TQStringList MediaManager::fullList() -{ - TQPtrList<Medium> list = m_mediaList.list(); - - TQStringList result; - - TQPtrList<Medium>::const_iterator it = list.begin(); - TQPtrList<Medium>::const_iterator end = list.end(); - for (; it!=end; ++it) - { - result+= (*it)->properties(); - result+= Medium::SEPARATOR; - } - - return result; -} - -TQStringList MediaManager::properties(const TQString &name) +const Medium* MediaManager::getMediumByName(const TQString &name) { const Medium *m = m_mediaList.findByName(name); - if (!m) { KURL u(name); - kdDebug() << "Media::prop " << name << " " << u.isValid() << endl; + kdDebug() << "Media::getMediumByName " << name << " " << u.isValid() << endl; if (u.isValid()) { if (u.protocol() == "system") { TQString path = u.path(); if (path.startsWith("/media/")) + { path = path.mid(strlen("/media/")); + } m = m_mediaList.findByName(path); kdDebug() << "findByName " << path << m << endl; } @@ -189,170 +144,162 @@ TQStringList MediaManager::properties(const TQString &name) { path = TDEStandardDirs::realFilePath(u.path()); kdDebug() << "comparing " << (*it)->mountPoint() << " " << path << " " << (*it)->deviceNode() << endl; - if ((*it)->mountPoint() == path || (*it)->deviceNode() == path) { - m = *it; - break; + if ((*it)->mountPoint() == path || (*it)->deviceNode() == path) + { + m = *it; + break; } } } } } + return m; +} + +TQStringList MediaManager::fullList() +{ + TQPtrList<Medium> list = m_mediaList.list(); + + TQStringList result; + + TQPtrList<Medium>::const_iterator it = list.begin(); + TQPtrList<Medium>::const_iterator end = list.end(); + for (; it!=end; ++it) + { + result+= (*it)->properties(); + result+= Medium::SEPARATOR; + } + + return result; +} - if (m) { +TQStringList MediaManager::properties(const TQString &name) +{ + const Medium *m = getMediumByName(name); + if (m) + { return m->properties(); } - else { + else + { return TQStringList(); } } TQStringList MediaManager::mountoptions(const TQString &name) { -#ifdef COMPILE_HALBACKEND - if (!m_halbackend) - return TQStringList(); - return m_halbackend->mountoptions(name); -#else // COMPILE_HALBACKEND - #ifdef COMPILE_TDEHARDWAREBACKEND - if (!m_tdebackend) - return TQStringList(); +#ifdef COMPILE_TDEHARDWAREBACKEND + if (m_tdebackend) + { return m_tdebackend->mountoptions(name); - #else // COMPILE_TDEHARDWAREBACKEND - return TQStringList(); - #endif // COMPILE_TDEHARDWAREBACKEND -#endif // COMPILE_HALBACKEND + } +#endif + return TQStringList(); } bool MediaManager::setMountoptions(const TQString &name, const TQStringList &options) { -#ifdef COMPILE_HALBACKEND - if (!m_halbackend) - return false; - return m_halbackend->setMountoptions(name, options); -#else // COMPILE_HALBACKEND - #ifdef COMPILE_TDEHARDWAREBACKEND - if (!m_tdebackend) - return false; +#ifdef COMPILE_TDEHARDWAREBACKEND + if (m_tdebackend) + { return m_tdebackend->setMountoptions(name, options); - #else // COMPILE_TDEHARDWAREBACKEND - return false; - #endif // COMPILE_TDEHARDWAREBACKEND -#endif // COMPILE_HALBACKEND + } +#endif + return false; } TQStringVariantMap MediaManager::mount(const TQString &uid) { - TQStringVariantMap result; #ifdef COMPILE_TDEHARDWAREBACKEND - if (!m_tdebackend) { - result["errStr"] = i18n("Feature only available with the TDE hardware backend"); - result["result"] = false; - return result; + if (m_tdebackend) + { + return m_tdebackend->mount(uid); } - return m_tdebackend->mount(uid); -#elif defined COMPILE_HALBACKEND - if (!m_halbackend) { - result["errStr"] = i18n("Feature only available with HAL"); - result["result"] = false; - return result; - } - return m_halbackend->mount(uid); #else - if (!m_fstabbackend) { - result["errStr"] = i18n("Feature only available with HAL or TDE hardware backend"); - result["result"] = false; - return result; + if (m_fstabbackend) + { + return m_fstabbackend->mount(uid); } - return m_fstabbackend->mount(uid); #endif + TQStringVariantMap result; + result["errStr"] = i18n("Feature only available with the TDE hardware or fstab backend"); + result["result"] = false; + return result; } TQStringVariantMap MediaManager::unmount(const TQString &uid) { - TQStringVariantMap result; #ifdef COMPILE_TDEHARDWAREBACKEND - if (!m_tdebackend) { - result["errStr"] = i18n("Feature only available with the TDE hardware backend"); - result["result"] = false; - return result; + if (m_tdebackend) + { + return m_tdebackend->unmount(uid); } - return m_tdebackend->unmount(uid); -#elif defined COMPILE_HALBACKEND - if (!m_halbackend) { - result["errStr"] = i18n("Feature only available with HAL"); - result["result"] = false; - return result; - } - return m_halbackend->unmount(uid); #else - if (!m_fstabbackend) { - result["errStr"] = i18n("Feature only available with HAL or TDE hardware backend"); - result["result"] = false; - return result; + if (m_fstabbackend) + { + return m_fstabbackend->unmount(uid); } - return m_fstabbackend->unmount(uid); #endif + TQStringVariantMap result; + result["errStr"] = i18n("Feature only available with the TDE hardware or fstab backend"); + result["result"] = false; + return result; } TQStringVariantMap MediaManager::unlock(const TQString &uid, const TQString &password) { - TQStringVariantMap result; -/* #ifdef COMPILE_TDEHARDWAREBACKEND - if (!m_tdebackend) { - result["errStr"] = i18n("Feature only available with the TDE hardware backend"); - result["result"] = false; - return result; - } - return m_tdebackend->unlock(uid, password); -#elif defined COMPILE_HALBACKEND -*/ -#if defined COMPILE_HALBACKEND - if (!m_halbackend) { - result["errStr"] = i18n("Feature only available with HAL"); - result["result"] = false; - return result; + if (m_tdebackend) + { + return m_tdebackend->unlock(uid, password); } - return m_halbackend->unlock(uid, password); - -#else -// if (!m_fstabbackend) { - result["errStr"] = i18n("Feature only available with HAL or TDE hardware backend"); - result["result"] = false; - return result; -// } -// return m_fstabbackend->unlock(uid, password); #endif + TQStringVariantMap result; + result["errStr"] = i18n("Feature only available with the TDE hardware backend"); + result["result"] = false; + return result; } -TQStringVariantMap MediaManager::lock(const TQString &uid) +TQStringVariantMap MediaManager::lock(const TQString &uid, bool releaseHolders) { +#ifdef COMPILE_TDEHARDWAREBACKEND + if (m_tdebackend) + { + return m_tdebackend->lock(uid, releaseHolders); + } +#endif TQStringVariantMap result; -/* + result["errStr"] = i18n("Feature only available with the TDE hardware backend"); + result["result"] = false; + return result; +} + +TQStringVariantMap MediaManager::eject(const TQString &uid) +{ #ifdef COMPILE_TDEHARDWAREBACKEND - if (!m_tdebackend) { - result["errStr"] = i18n("Feature only available with the TDE hardware backend"); - result["result"] = false; - return result; + if (m_tdebackend) + { + return m_tdebackend->eject(uid); } - return m_tdebackend->lock(uid); -#elif defined COMPILE_HALBACKEND -*/ -#if defined COMPILE_HALBACKEND - if (!m_halbackend) { - result["errStr"] = i18n("Feature only available with HAL"); - result["result"] = false; - return result; +#endif + TQStringVariantMap result; + result["errStr"] = i18n("Feature only available with the TDE hardware backend"); + result["result"] = false; + return result; +} + +TQStringVariantMap MediaManager::safeRemove(const TQString &uid) +{ +#ifdef COMPILE_TDEHARDWAREBACKEND + if (m_tdebackend) + { + return m_tdebackend->safeRemove(uid); } - return m_halbackend->lock(uid); -#else -// if (!m_fstabbackend) { - result["errStr"] = i18n("Feature only available with HAL or TDE hardware backend"); - result["result"] = false; - return result; -// } -// return m_fstabbackend->lock(uid); #endif + TQStringVariantMap result; + result["errStr"] = i18n("Feature only available with the TDE hardware backend"); + result["result"] = false; + return result; } TQStringVariantMap MediaManager::mountByNode(const TQString &deviceNode) @@ -391,7 +338,7 @@ TQStringVariantMap MediaManager::unlockByNode(const TQString &deviceNode, const return unlock(medium->id(), password); } -TQStringVariantMap MediaManager::lockByNode(const TQString &deviceNode) +TQStringVariantMap MediaManager::lockByNode(const TQString &deviceNode, bool releaseHolders) { const Medium *medium = m_mediaList.findByNode(deviceNode); if (!medium) { @@ -400,7 +347,44 @@ TQStringVariantMap MediaManager::lockByNode(const TQString &deviceNode) result["result"] = false; return result; } - return lock(medium->id()); + return lock(medium->id(), releaseHolders); +} + +TQStringVariantMap MediaManager::ejectByNode(const TQString &deviceNode) +{ + const Medium *medium = m_mediaList.findByNode(deviceNode); + if (!medium) { + TQStringVariantMap result; + result["errStr"] = i18n("No such medium: %1").arg(deviceNode); + result["result"] = false; + return result; + } + return eject(medium->id()); +} + +TQStringVariantMap MediaManager::safeRemoveByNode(const TQString &deviceNode) +{ + const Medium *medium = m_mediaList.findByNode(deviceNode); + if (!medium) { + TQStringVariantMap result; + result["errStr"] = i18n("No such medium: %1").arg(deviceNode); + result["result"] = false; + return result; + } + return safeRemove(medium->id()); +} + +TQString MediaManager::mimeType(const TQString &name) +{ + const Medium *m = getMediumByName(name); + if (m) + { + return m->mimeType(); + } + else + { + return TQString::null; + } } TQString MediaManager::nameForLabel(const TQString &label) diff --git a/tdeioslave/media/mediamanager/mediamanager.h b/tdeioslave/media/mediamanager/mediamanager.h index d8a31d8e1..1fe873f98 100644 --- a/tdeioslave/media/mediamanager/mediamanager.h +++ b/tdeioslave/media/mediamanager/mediamanager.h @@ -29,18 +29,19 @@ #include "removablebackend.h" #include "mediadirnotify.h" -class HALBackend; class TDEBackend; class FstabBackend; class MediaManager : public KDEDModule { -Q_OBJECT +TQ_OBJECT K_DCOP public: MediaManager(const TQCString &obj); ~MediaManager(); + const Medium* getMediumByName(const TQString &name); + k_dcop: TQStringList fullList(); TQStringList properties(const TQString &name); @@ -50,19 +51,23 @@ k_dcop: TQStringVariantMap mount(const TQString &uid); TQStringVariantMap unmount(const TQString &uid); TQStringVariantMap unlock(const TQString &uid, const TQString &password); - TQStringVariantMap lock(const TQString &uid); + TQStringVariantMap lock(const TQString &uid, bool releaseHolders); + TQStringVariantMap eject(const TQString &uid); + TQStringVariantMap safeRemove(const TQString &uid); TQStringVariantMap mountByNode(const TQString &deviceNode); TQStringVariantMap unmountByNode(const TQString &deviceNode); TQStringVariantMap unlockByNode(const TQString &deviceNode, const TQString &password); - TQStringVariantMap lockByNode(const TQString &deviceNode); + TQStringVariantMap lockByNode(const TQString &deviceNode, bool releaseHolders); + TQStringVariantMap ejectByNode(const TQString &deviceNode); + TQStringVariantMap safeRemoveByNode(const TQString &deviceNode); + TQString mimeType(const TQString &name); TQString nameForLabel(const TQString &label); ASYNC setUserLabel(const TQString &name, const TQString &label); ASYNC reloadBackends(); - // Removable media handling (for people not having HAL) bool removablePlug(const TQString &devNode, const TQString &label); bool removableUnplug(const TQString &devNode); bool removableCamera(const TQString &devNode); @@ -91,7 +96,6 @@ private: MediaList m_mediaList; TQValueList<BackendBase*> m_backends; RemovableBackend *mp_removableBackend; - HALBackend *m_halbackend; TDEBackend *m_tdebackend; MediaDirNotify m_dirNotify; FstabBackend *m_fstabbackend; diff --git a/tdeioslave/media/mediamanager/removablebackend.cpp b/tdeioslave/media/mediamanager/removablebackend.cpp index 54df3d6f1..a9207cd92 100644 --- a/tdeioslave/media/mediamanager/removablebackend.cpp +++ b/tdeioslave/media/mediamanager/removablebackend.cpp @@ -37,8 +37,8 @@ RemovableBackend::RemovableBackend(MediaList &list) { KDirWatch::self()->addFile(MTAB); - connect( KDirWatch::self(), TQT_SIGNAL( dirty(const TQString&) ), - this, TQT_SLOT( slotDirty(const TQString&) ) ); + connect( KDirWatch::self(), TQ_SIGNAL( dirty(const TQString&) ), + this, TQ_SLOT( slotDirty(const TQString&) ) ); KDirWatch::self()->startScan(); } @@ -63,8 +63,11 @@ bool RemovableBackend::plug(const TQString &devNode, const TQString &label) if (!m_removableIds.contains(id)) { Medium *medium = new Medium(id, id, name); - medium->mountableState(devNode, TQString::null, - TQString::null, false); + medium->setMountable(true); + medium->setDeviceNode(devNode); + medium->setMountPoint(TQString::null); + medium->setFsType(TQString::null); + medium->setMounted(false); TQStringList words = TQStringList::split(" ", label); diff --git a/tdeioslave/media/mediamanager/removablebackend.h b/tdeioslave/media/mediamanager/removablebackend.h index fa16a391b..256497d9a 100644 --- a/tdeioslave/media/mediamanager/removablebackend.h +++ b/tdeioslave/media/mediamanager/removablebackend.h @@ -26,7 +26,7 @@ class RemovableBackend : public TQObject, public BackendBase { -Q_OBJECT +TQ_OBJECT public: RemovableBackend(MediaList &list); diff --git a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp index c399d280d..a5900c883 100644 --- a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp +++ b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp @@ -49,16 +49,15 @@ TDEBackend::TDEBackend(MediaList &list, TQObject* parent) : TQObject() , BackendBase(list) - , m_unlockDialog(0) , m_parent(parent) { // Initialize the TDE device manager TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); // Connect device monitoring signals/slots - connect(hwdevices, TQT_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQT_SLOT(AddDeviceHandler(TDEGenericDevice*))); - connect(hwdevices, TQT_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQT_SLOT(RemoveDeviceHandler(TDEGenericDevice*))); - connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(ModifyDeviceHandler(TDEGenericDevice*))); + connect(hwdevices, TQ_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQ_SLOT(AddDeviceHandler(TDEGenericDevice*))); + connect(hwdevices, TQ_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQ_SLOT(RemoveDeviceHandler(TDEGenericDevice*))); + connect(hwdevices, TQ_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQ_SLOT(ModifyDeviceHandler(TDEGenericDevice*))); // List devices at startup ListDevices(); @@ -139,29 +138,30 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification) bool allowDialogNotification = allowNotification; TDEConfig config("mediamanagerrc"); config.setGroup("Global"); - if (!config.readBoolEntry("NotificationPopupsEnabled", false)) { + if (!config.readBoolEntry("NotificationPopupsEnabled", true)) { allowDialogNotification = false; } // Add volume block devices if (sdevice->isDiskOfType(TDEDiskDeviceType::HDD)) { /* We only list volumes that... - * - are encrypted with LUKS or + * - are encrypted or * - have a filesystem or * - have an audio track */ - if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) - && !(sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + if (!sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem) && + !sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank) ) { // } - /* We also don't display devices that underlie other devices; - * e.g. the raw partition of a device mapper volume - */ - else if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice) - || (sdevice->fileSystemUsage().upper() == "RAID")) { + // We also don't display devices that underlie other devices, unless they are encrypted devices + else if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice) && + !sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) || + sdevice->fileSystemUsage().upper() == "RAID") { // } else { @@ -169,16 +169,6 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification) Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); setVolumeProperties(medium); - // Do not list the LUKS backend device if it has been unlocked elsewhere - if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { - if (sdevice->holdingDevices().count() > 0) { - medium->setHidden(true); - } - else { - medium->setHidden(false); - } - } - // Hide udev hidden devices by default but allow the user to override if desired via Show Hidden Files if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hidden)) { medium->setSoftHidden(true); @@ -266,33 +256,29 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification) } /* We only list volumes that... - * - are encrypted with LUKS or + * - are encrypted or * - have a filesystem or - * - are a floppy disk + * - have an audio track */ - if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) - && !(sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + if (!sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem) && + !sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank) ) { // } + // We also don't display devices that underlie other devices, unless they are encrypted devices + else if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice) && + !sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) || + sdevice->fileSystemUsage().upper() == "RAID") { + // + } else { // Create medium Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); - setFloppyProperties(medium); - - // Do not list the LUKS backend device if it has been unlocked elsewhere - if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { - if (sdevice->holdingDevices().count() > 0) { - medium->setHidden(true); - } - else { - medium->setHidden(false); - } - } - m_mediaList.addMedium(medium, allowDialogNotification); kdDebug(1219) << "TDEBackend::AddDevice inserted floppy medium for " << sdevice->uniqueID() << endl; @@ -334,8 +320,7 @@ void TDEBackend::ModifyDevice(TDEStorageDevice * sdevice) { kdDebug(1219) << "TDEBackend::ModifyDevice for " << sdevice->uniqueID() << endl; - bool allowNotification = false; - ResetProperties(sdevice, allowNotification); + ResetProperties(sdevice, false); } void TDEBackend::ResetProperties(TDEStorageDevice * sdevice, bool allowNotification, bool overrideIgnoreList) @@ -359,24 +344,28 @@ void TDEBackend::ResetProperties(TDEStorageDevice * sdevice, bool allowNotificat Medium* m = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), ""); // Keep these conditions in sync with ::AddDevice above, OR ELSE!!! - // BEGIN if (sdevice->isDiskOfType(TDEDiskDeviceType::HDD)) { - if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) - && !(sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + /* We only list volumes that... + * - are encrypted or + * - have a filesystem or + * - have an audio track + */ + if (!sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem) && + !sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank) ) { + // + } + // We also don't display devices that underlie other devices, unless they are encrypted devices + else if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice) && + !sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) || + sdevice->fileSystemUsage().upper() == "RAID") { + // } else { - // Do not list the LUKS backend device if it has been unlocked elsewhere - if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { - if (sdevice->holdingDevices().count() > 0) { - m->setHidden(true); - } - else { - m->setHidden(false); - } - } setVolumeProperties(m); } } @@ -416,25 +405,27 @@ void TDEBackend::ResetProperties(TDEStorageDevice * sdevice, bool allowNotificat (sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) || (sdevice->isDiskOfType(TDEDiskDeviceType::Jaz)) ) { - - if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)) - && !(sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) - && !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) + /* We only list volumes that... + * - are encrypted or + * - have a filesystem or + * - have an audio track + */ + if (!sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem) && + !sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio) && + !sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank) ) { // } + // We also don't display devices that underlie other devices, unless they are encrypted devices + else if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice) && + !sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) && + !sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) || + sdevice->fileSystemUsage().upper() == "RAID") { + // + } else { - // Do not list the LUKS backend device if it has been unlocked elsewhere - if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { - if (sdevice->holdingDevices().count() > 0) { - m->setHidden(true); - } - else { - m->setHidden(false); - } - } - setFloppyProperties(m); } } @@ -443,8 +434,6 @@ void TDEBackend::ResetProperties(TDEStorageDevice * sdevice, bool allowNotificat setCameraProperties(m); } - // END - if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) && (!(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Inserted)))) { kdDebug(1219) << "TDEBackend::ResetProperties for " << sdevice->uniqueID() << " device was removed from system" << endl; RemoveDevice(sdevice); @@ -462,27 +451,40 @@ void TDEBackend::setVolumeProperties(Medium* medium) TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); - TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id()); + TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); if (!sdevice) { return; } medium->setName(generateName(sdevice->deviceNode())); - if ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) || (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt))) { + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) { medium->setEncrypted(true); + medium->setLocked(!sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt)); } else { medium->setEncrypted(false); } - // USAGE: mountableState(Device node, Mount point, Filesystem type, Mounted ?) - medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull()); + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) || + sdevice->fileSystemUsage().upper() == "RAID") { + // Encrypted disks or device underlying other devices are not mountable + medium->setMountable(false); + } + else { + medium->setMountable(true); + } + + medium->setDeviceNode(sdevice->deviceNode()); + medium->setMountPoint(sdevice->mountPath()); + medium->setFsType(sdevice->fileSystemName()); + medium->setMounted(!sdevice->mountPath().isEmpty()); TQString diskLabel = sdevice->diskLabel(); bool useDefaultLabel = diskLabel.isNull(); if (useDefaultLabel) { diskLabel = i18n("%1 Removable Device").arg(sdevice->deviceFriendlySize()); } + diskLabel += " (" + sdevice->deviceNode() + ")"; TQString mimeType; @@ -518,14 +520,15 @@ void TDEBackend::setVolumeProperties(Medium* medium) // Default mimeType = "media/cdrom" + MOUNT_MEDIA_SUFFIX; if (useDefaultLabel) { - diskLabel = i18n("%1 Removable Device").arg(sdevice->deviceFriendlySize()); + diskLabel = i18n("%1 Removable Disk (%2)").arg(sdevice->deviceFriendlySize(), sdevice->deviceNode()); } if (sdevice->isDiskOfType(TDEDiskDeviceType::CDROM)) { mimeType = "media/cdrom" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankcd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank CD-ROM"); } } @@ -534,7 +537,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/cd-r" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankcd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank CD-R"); } } @@ -543,7 +547,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/cd-rw" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankcd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank CD-RW"); } } @@ -552,7 +557,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/cd-rw" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankcd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Magneto-Optical CD"); } } @@ -561,7 +567,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/cd-rw" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankcd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Mount Ranier CD-RW"); } } @@ -570,7 +577,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/cd-rw" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankcd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Mount Ranier CD-RW-W"); } } @@ -579,7 +587,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank DVD-ROM"); } } @@ -588,7 +597,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank DVD-RAM"); } } @@ -597,7 +607,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank DVD-R"); } } @@ -606,7 +617,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank DVD-RW"); } } @@ -615,7 +627,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Dual Layer DVD-R"); } } @@ -624,7 +637,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Dual Layer DVD-RW"); } } @@ -633,7 +647,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank DVD+R"); } } @@ -642,7 +657,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank DVD+RW"); } } @@ -651,7 +667,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Dual Layer DVD+R"); } } @@ -660,7 +677,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/dvd" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankdvd"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank Dual Layer DVD+RW"); } } @@ -669,7 +687,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankbluray"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank BLURAY-ROM"); } } @@ -678,7 +697,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankbluray"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank BLURAY-R"); } } @@ -687,7 +707,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankbluray"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank BLURAY-RW"); } } @@ -696,7 +717,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankbluray"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank HDDVD-ROM"); } } @@ -705,7 +727,8 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankbluray"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank HDDVD-R"); } } @@ -714,14 +737,16 @@ void TDEBackend::setVolumeProperties(Medium* medium) mimeType = "media/bluray" + MOUNT_MEDIA_SUFFIX; if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) { mimeType = "media/blankbluray"; - medium->unmountableState(""); + medium->setMountable(false); + medium->setBaseURL(TQString::null); diskLabel = i18n("Blank HDDVD-RW"); } } if (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) { mimeType = "media/audiocd"; - medium->unmountableState("audiocd:/?device=" + sdevice->deviceNode()); + medium->setMountable(false); + medium->setBaseURL("audiocd:/?device=" + sdevice->deviceNode()); diskLabel = i18n("Audio CD"); } @@ -746,12 +771,11 @@ void TDEBackend::setVolumeProperties(Medium* medium) diskLabel = i18n("%1 Fixed Disk (%2)").arg(sdevice->deviceFriendlySize(), sdevice->deviceNode()); } - if (sdevice->isDiskOfType(TDEDiskDeviceType::USB) - || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable) - || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { + if (sdevice->isDiskOfType(TDEDiskDeviceType::USB) || + sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) { mimeType = "media/removable" + MOUNT_MEDIA_SUFFIX; if (useDefaultLabel) { - diskLabel = i18n("%1 Removable Device").arg(sdevice->deviceFriendlySize()); + diskLabel = i18n("%1 Removable Disk (%2)").arg(sdevice->deviceFriendlySize(), sdevice->deviceNode()); } } @@ -769,9 +793,10 @@ void TDEBackend::setVolumeProperties(Medium* medium) } if (sdevice->isDiskOfType(TDEDiskDeviceType::MediaDevice)) { medium->setIconName("ipod" + MOUNTED_ICON_SUFFIX); - if (sdevice->vendorModel().upper().contains("IPOD") && KProtocolInfo::isKnownProtocol( TQString("ipod") ) ) { - medium->unmountableState( "ipod:/" ); - medium->mountableState(!sdevice->mountPath().isNull()); + if (sdevice->vendorModel().upper().contains("IPOD") && KProtocolInfo::isKnownProtocol(TQString("ipod"))) { + medium->setBaseURL("ipod:/"); + medium->setMountable(true); + medium->setMounted(!sdevice->mountPath().isEmpty()); } } if (sdevice->isDiskOfType(TDEDiskDeviceType::Tape)) { @@ -782,15 +807,6 @@ void TDEBackend::setVolumeProperties(Medium* medium) } } - if (!medium->needMounting()) { - if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { - if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice)) { - // Encrypted base devices must be set to this mimetype or they won't open when the base device node is passed to the tdeioslave - mimeType = "media/removable_mounted"; - } - } - } - medium->setLabel(diskLabel); medium->setMimeType(mimeType); } @@ -813,22 +829,38 @@ bool TDEBackend::setFloppyProperties(Medium* medium) // Any more? if ((sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) || (sdevice->isDiskOfType(TDEDiskDeviceType::Jaz))) { medium->setName(generateName(sdevice->deviceNode())); - if ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) || (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt))) { + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) { medium->setEncrypted(true); + medium->setLocked(!sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt)); } else { medium->setEncrypted(false); } - // USAGE: mountableState(Device node, Mount point, Filesystem type, Mounted ?) - medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull()); + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) || + sdevice->fileSystemUsage().upper() == "RAID") { + // Encrypted disks or device underlying other devices are not mountable + medium->setMountable(false); + } + else { + medium->setMountable(true); + } + + medium->setDeviceNode(sdevice->deviceNode()); + medium->setMountPoint(sdevice->mountPath()); + medium->setFsType(sdevice->fileSystemName()); + medium->setMounted(!sdevice->mountPath().isEmpty()); } if (sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) { setFloppyMountState(medium); // We don't use the routine above as floppy disks are extremely slow (we don't want them accessed at all during media listing) - medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull()); + medium->setMountable(true); + medium->setDeviceNode(sdevice->deviceNode()); + medium->setMountPoint(sdevice->mountPath()); + medium->setFsType(sdevice->fileSystemName()); + medium->setMounted(!sdevice->mountPath().isEmpty()); if (sdevice->mountPath().isNull()) { medium->setMimeType("media/floppy_unmounted"); @@ -850,7 +882,7 @@ bool TDEBackend::setFloppyProperties(Medium* medium) // Set label TQString diskLabel = sdevice->diskLabel(); if (diskLabel.isNull()) { - diskLabel = i18n("%1 Zip Disk").arg(sdevice->deviceFriendlySize()); + diskLabel = i18n("%1 Zip Disk (%2)").arg(sdevice->deviceFriendlySize(), sdevice->deviceNode()); } medium->setLabel(diskLabel); } @@ -885,7 +917,8 @@ void TDEBackend::setCameraProperties(Medium* medium) device.sprintf("camera://@[usb:%s,%s]/", devNode0.ascii(), devNode1.ascii()); } - medium->unmountableState(device); + medium->setMountable(false); + medium->setBaseURL(device); medium->setMimeType("media/gphoto2camera"); medium->setIconName(TQString::null); @@ -909,7 +942,11 @@ void TDEBackend::setFloppyMountState( Medium *medium ) if ((*it)->mountedFrom() == medium->deviceNode() ) { fstype = (*it)->mountType().isNull() ? (*it)->mountType() : "auto"; mountpoint = (*it)->mountPoint(); - medium->mountableState( medium->deviceNode(), mountpoint, fstype, true ); + medium->setMountable(true); + medium->setDeviceNode(medium->deviceNode()); + medium->setMountPoint(mountpoint); + medium->setFsType(fstype); + medium->setMounted(true); return; } } @@ -997,7 +1034,7 @@ TQStringList TDEBackend::mountoptions(const TQString &name) bool removable = false; if (!drive_udi.isNull()) { - removable = ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) || (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable))); + removable = sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable); } TQString tmp; @@ -1173,23 +1210,19 @@ bool TDEBackend::setMountoptions(const TQString &name, const TQStringList &optio return true; } -void TDEBackend::slotPasswordReady() { - m_decryptionPassword = m_unlockDialog->getPassword(); - m_decryptPasswordValid = true; -} - -void TDEBackend::slotPasswordCancel() { - m_decryptionPassword = TQString::null; - m_decryptPasswordValid = true; -} - TQStringVariantMap TDEBackend::mount(const Medium *medium) { kdDebug(1219) << "TDEBackend::mount for medium " << medium->name() << endl; TQStringVariantMap result; - if (medium->isMounted()) { - result["result"] = true; + if (!medium->isMountable()) { + result["errStr"] = i18n("%1 is not a mountable media.").arg(medium->deviceNode()); + result["result"] = false; + return result; + } + else if (medium->isMounted()) { + result["errStr"] = i18n("%1 is already mounted to %2.").arg(medium->deviceNode()).arg(medium->mountPoint()); + result["result"] = false; return result; } @@ -1201,7 +1234,7 @@ TQStringVariantMap TDEBackend::mount(const Medium *medium) data.medium = medium; TDEIO::Job *job = TDEIO::mount(false, 0, medium->deviceNode(), mountPoint); - connect(job, TQT_SIGNAL(result(TDEIO::Job*)), TQT_SLOT(slotResult(TDEIO::Job*))); + connect(job, TQ_SIGNAL(result(TDEIO::Job*)), TQ_SLOT(slotResult(TDEIO::Job*))); mount_jobs[job] = &data; // The caller expects the device to be mounted when the function // completes. Thus block until the job completes. @@ -1222,7 +1255,7 @@ TQStringVariantMap TDEBackend::mount(const Medium *medium) TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); if (!sdevice) { - result["errStr"] = i18n("Internal error. Couldn't find medium."); + result["errStr"] = i18n("Internal error. Couldn't find medium id %1.").arg(medium->id()); result["result"] = false; return result; } @@ -1242,99 +1275,13 @@ TQStringVariantMap TDEBackend::mount(const Medium *medium) } TQString qerror; - if (!medium->isEncrypted()) { - // normal volume - TQStringVariantMap mountResult = sdevice->mountDevice(diskLabel, valids); - TQString mountedPath = mountResult.contains("mountPath") ? mountResult["mountPath"].toString() : TQString::null; - if (mountedPath.isEmpty()) { - qerror = i18n("Unable to mount this device."); - TQString errStr = mountResult.contains("errStr") ? mountResult["errStr"].toString() : TQString::null; - if (!errStr.isEmpty()) { - qerror.append(i18n("<p>Technical details:<br>").append(errStr)); - } - } - } - else { - TQString iconName = medium->iconName(); - if (iconName.isEmpty()) - { - TQString mime = medium->mimeType(); - iconName = KMimeType::mimeType(mime)->icon(mime, false); - } - - bool continue_trying_to_decrypt = true; - while (continue_trying_to_decrypt == true) { - m_decryptPasswordValid = false; - - m_unlockDialog = new Dialog(sdevice->deviceNode(), iconName); - m_unlockDialog->show(); - - connect(m_unlockDialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotPasswordReady())); - connect(m_unlockDialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotPasswordCancel())); - connect(this, TQT_SIGNAL (signalDecryptionPasswordError(TQString)), m_unlockDialog, TQT_SLOT (slotDialogError(TQString))); - - while (m_decryptPasswordValid == false) { - tqApp->processEvents(); - } - - m_unlockDialog->setEnabled(false); - tqApp->processEvents(); - - if (m_decryptionPassword.isNull()) { - delete m_unlockDialog; - result["errStr"] = i18n("Decryption aborted"); - result["result"] = false; - return result; - } - else { - // Just for some added fun, if udev emits a medium change event, which I then forward, with mounted==0, it stops the MediaProtocol::listDir method dead in its tracks, - // and therefore the media:/ tdeioslave won't refresh after the encrypted device mount - // Therefore, I need to ignore all change events on this device during the mount process and hope nothing bad happens as a result! - if (!m_ignoreDeviceChangeEvents.contains(sdevice->uniqueID())) { - m_ignoreDeviceChangeEvents.append(sdevice->uniqueID()); - } - - // mount encrypted volume with password - TQStringVariantMap mountResult = sdevice->mountEncryptedDevice(m_decryptionPassword, diskLabel, valids); - TQString mountedPath = mountResult.contains("mountPath") ? mountResult["mountPath"].toString() : TQString::null; - if (mountedPath.isEmpty()) { - if (mountResult.contains("retCode") && mountResult["retCode"].toInt() == 0) { - // Mounting was successful - // Because the TDE hardware backend is event driven it might take a little while for the new enlock mapped device to show up - // Wait up to 30 seconds for it to appear... - for (int i=0;i<300;i++) { - mountedPath = sdevice->mountPath(); - if (!mountedPath.isEmpty()) { - break; - } - tqApp->processEvents(50); - usleep(50000); - } - } - } - if (mountedPath.isEmpty()) { - if (mountResult.contains("retCode") && mountResult["retCode"].toInt() == 25600) { - // Probable LUKS failure - // Retry - m_unlockDialog->setEnabled(true); - continue_trying_to_decrypt = true; - } - else { - qerror = i18n("Cannot mount encrypted locked drives!"); - qerror = i18n("Unable to mount this device."); - TQString errStr = mountResult.contains("errStr") ? mountResult["errStr"].toString() : TQString::null; - if (!errStr.isEmpty()) { - qerror.append(i18n("<p>Technical details:<br>").append(errStr)); - } - continue_trying_to_decrypt = false; - } - } - else { - continue_trying_to_decrypt = false; - } - - delete m_unlockDialog; - } + TQStringVariantMap mountResult = sdevice->mountDevice(diskLabel, valids); + TQString mountedPath = mountResult.contains("mountPath") ? mountResult["mountPath"].toString() : TQString::null; + if (mountedPath.isEmpty()) { + qerror = i18n("<b>Unable to mount this device.</b>"); + TQString errStr = mountResult.contains("errStr") ? mountResult["errStr"].toString() : TQString::null; + if (!errStr.isEmpty()) { + qerror.append(i18n("<p>Technical details:<br>").append(errStr)); } } @@ -1373,16 +1320,20 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) kdDebug(1219) << "TDEBackend::unmount for id " << id << endl; TQStringVariantMap result; - - const Medium* medium = m_mediaList.findById(id); + const Medium *medium = m_mediaList.findById(id); if (!medium) { result["errStr"] = i18n("No such medium: %1").arg(id); result["result"] = false; return result; } - - if (!medium->isMounted()) { - result["result"] = true; + else if (!medium->isMountable()) { + result["errStr"] = i18n("%1 is not a mountable media.").arg(medium->deviceNode()); + result["result"] = false; + return result; + } + else if (!medium->isMounted()) { + result["errStr"] = i18n("%1 is already unmounted.").arg(medium->deviceNode()); + result["result"] = false; return result; } @@ -1394,7 +1345,7 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) data.medium = medium; TDEIO::Job *job = TDEIO::unmount( medium->mountPoint(), false ); - connect(job, TQT_SIGNAL(result(TDEIO::Job*)), TQT_SLOT(slotResult(TDEIO::Job*))); + connect(job, TQ_SIGNAL(result(TDEIO::Job*)), TQ_SLOT(slotResult(TDEIO::Job*))); mount_jobs[job] = &data; // The caller expects the device to be unmounted when the function // completes. Thus block until the job completes. @@ -1415,7 +1366,7 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); if (!sdevice) { - result["errStr"] = i18n("Internal error. Couldn't find medium."); + result["errStr"] = i18n("Internal error. Couldn't find medium id %1.").arg(medium->id()); result["result"] = false; return result; } @@ -1428,7 +1379,7 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) TQStringVariantMap unmountResult = sdevice->unmountDevice(); if (unmountResult["result"].toBool() == false) { // Unmount failed! - qerror = i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at " + qerror = i18n("The device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at " "<b>%4</b> could not be unmounted. ").arg("system:/media/" + medium->name(), medium->deviceNode(), medium->prettyLabel(), medium->prettyBaseURL().pathOrURL()); TQString errStr = unmountResult.contains("errStr") ? unmountResult["errStr"].toString() : TQString::null; @@ -1441,7 +1392,7 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) // Failed as BUSY TQString processesUsingDev = listUsingProcesses(medium); if (!processesUsingDev.isNull()) { - if (KMessageBox::warningYesNo(0, i18n("<qt>The device <b>%1</b> (%2) named <b>'%3'</b> and currently " + if (KMessageBox::warningYesNo(0, i18n("The device <b>%1</b> (%2) named <b>'%3'</b> and currently " "mounted at <b>%4</b> can not be unmounted at this time.<p>%5<p><b>Would you like to forcibly " "terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg("system:/media/" + medium->name()).arg(medium->deviceNode()).arg(medium->prettyLabel()).arg(medium->prettyBaseURL().pathOrURL()) @@ -1450,7 +1401,7 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) unmountResult = sdevice->unmountDevice(); if (unmountResult["result"].toBool() == false) { // Unmount failed! - qerror = i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at " + qerror = i18n("The device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at " "<b>%4</b> could not be unmounted. ").arg("system:/media/" + medium->name(), medium->deviceNode(), medium->prettyLabel(), medium->prettyBaseURL().pathOrURL()); TQString errStr = unmountResult.contains("errStr") ? unmountResult["errStr"].toString() : TQString::null; @@ -1476,10 +1427,225 @@ TQStringVariantMap TDEBackend::unmount(const TQString &id) m_mediaList.removeMedium(uid, true); } + ResetProperties(sdevice, false, true); + result["result"] = true; + return result; +} + +TQStringVariantMap TDEBackend::unlock(const TQString &id, const TQString &password) +{ + kdDebug(1219) << "TDEBackend::unlock for id " << id << endl; + + TQStringVariantMap result; + const Medium *medium = m_mediaList.findById(id); + if (!medium) { + result["errStr"] = i18n("No such medium: %1").arg(id); + result["result"] = false; + return result; + } + else if (!medium->isEncrypted()) { + result["errStr"] = i18n("%1 is not an encrypted media.").arg(medium->deviceNode()); + result["result"] = false; + return result; + } + else if (!medium->needUnlocking()) { + result["errStr"] = i18n("%1 is already unlocked.").arg(medium->deviceNode()); + result["result"] = false; + return result; + } + + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + result["errStr"] = i18n("Internal error. Couldn't find medium id %1.").arg(medium->id()); + result["result"] = false; + return result; + } + + TQStringVariantMap unlockResult = sdevice->unlockDevice(password); + if (unlockResult["result"].toBool() == false) { + TQString qerror = i18n("<b>Unable to unlock the device.</b>"); + TQString errStr = unlockResult.contains("errStr") ? unlockResult["errStr"].toString() : TQString::null; + if (!errStr.isEmpty()) { + qerror.append(i18n("<p>Technical details:<br>").append(errStr)); + result["errStr"] = qerror; + result["result"] = false; + return result; + } + } + + ResetProperties(sdevice, false, true); + result["result"] = true; + return result; +} + +TQStringVariantMap TDEBackend::lock(const TQString &id, bool releaseHolders) +{ + kdDebug(1219) << "TDEBackend::lock for id " << id << ", release holders " + << releaseHolders << endl; + + TQStringVariantMap result; + + const Medium *medium = m_mediaList.findById(id); + if (!medium) { + result["errStr"] = i18n("No such medium: %1").arg(id); + result["result"] = false; + return result; + } + else if (!medium->isEncrypted()) { + result["errStr"] = i18n("%1 is not an encrypted media.").arg(medium->deviceNode()); + result["result"] = false; + return result; + } + else if (medium->needUnlocking()) { + result["errStr"] = i18n("%1 is already locked.").arg(medium->deviceNode()); + result["result"] = false; + return result; + } + + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) { + result["errStr"] = i18n("Internal error. Couldn't find medium id %1.").arg(medium->id()); + result["result"] = false; + return result; + } + + // Release device holders if requested + if (releaseHolders) + { + releaseHolderDevices(medium->deviceNode(), false); + } + + TQStringVariantMap lockResult = sdevice->lockDevice(); + if (lockResult["result"].toBool() == false) { + TQString qerror = i18n("<b>Unable to lock the device.</b>"); + TQString errStr = lockResult.contains("errStr") ? lockResult["errStr"].toString() : TQString::null; + if (!errStr.isEmpty()) { + qerror.append(i18n("<p>Technical details:<br>").append(errStr)); + result["errStr"] = qerror; + result["result"] = false; + return result; + } + } + + ResetProperties(sdevice, false, true); result["result"] = true; return result; } +TQStringVariantMap TDEBackend::eject(const TQString &id) +{ + kdDebug(1219) << "TDEBackend::eject for id " << id << endl; + + TQStringVariantMap result; + + const Medium *medium = m_mediaList.findById(id); + if (!medium) + { + result["errStr"] = i18n("No such medium: %1").arg(id); + result["result"] = false; + return result; + } + + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); + if (!sdevice) + { + result["errStr"] = i18n("Internal error. Couldn't find medium id %1.").arg(medium->id()); + result["result"] = false; + return result; + } + + TQStringVariantMap ejectResult = sdevice->ejectDrive(); + if (ejectResult["result"].toBool() == false) + { + TQString qerror = i18n("<b>Unable to eject the device.</b>"); + TQString errStr = ejectResult.contains("errStr") ? ejectResult["errStr"].toString() : TQString::null; + if (!errStr.isEmpty()) + { + qerror.append(i18n("<p>Technical details:<br>").append(errStr)); + result["errStr"] = qerror; + result["result"] = false; + return result; + } + } + + result["result"] = true; + return result; +} + +TQStringVariantMap TDEBackend::safeRemove(const TQString &id) +{ + kdDebug(1219) << "TDEBackend::safeRemove for id " << id << endl; + + TQStringVariantMap result; + + const Medium *medium = m_mediaList.findById(id); + if (!medium) + { + result["errStr"] = i18n("No such medium: %1").arg(id); + result["result"] = false; + return result; + } + + releaseHolderDevices(medium->deviceNode(), true); + return eject(id); +} + +void TDEBackend::releaseHolderDevices(const TQString &deviceNode, bool handleThis) +{ + kdDebug(1219) << "TDEBackend::releaseHolderDevices for node " << deviceNode + << ", handle this " << (handleThis ? "yes" : "no") << endl; + + const Medium *medium = m_mediaList.findByNode(deviceNode); + if (!medium) + { + return; + } + + // Scan the holding devices and unmount/lock them if possible + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEStorageDevice *sdevice = hwdevices->findDiskByUID(medium->id()); + if (sdevice) + { + TQStringList holdingDeviceList = sdevice->holdingDevices(); + for (TQStringList::Iterator holdingDevIt = holdingDeviceList.begin(); holdingDevIt != holdingDeviceList.end(); ++holdingDevIt) + { + TDEGenericDevice *hwHolderDevice = hwdevices->findBySystemPath(*holdingDevIt); + if (hwHolderDevice->type() == TDEGenericDeviceType::Disk) + { + TDEStorageDevice *holderSDevice = static_cast<TDEStorageDevice*>(hwHolderDevice); + const Medium *holderMedium = m_mediaList.findByNode(holderSDevice->deviceNode()); + if (holderMedium && !holderMedium->id().isEmpty()) + { + releaseHolderDevices(holderMedium->deviceNode(), true); + } + } + } + } + + if (handleThis) + { + // Unmount if necessary + if (medium->isMountable() && medium->isMounted()) + { + unmount(medium->id()); + // Must process udev events before continuing, to make sure all + // affected devices are properly updated + tqApp->processEvents(); + } + // Lock if necessary. + if (medium->isEncrypted() && !medium->isLocked()) + { + lock(medium->id(), false); + // Must process udev events before continuing, to make sure all + // affected devices are properly updated + tqApp->processEvents(); + } + } +} + void TDEBackend::slotResult(TDEIO::Job *job) { TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); @@ -1491,8 +1657,7 @@ void TDEBackend::slotResult(TDEIO::Job *job) if (job->error() == TDEIO::ERR_COULD_NOT_UNMOUNT) { TQString proclist(listUsingProcesses(medium)); - qerror = "<qt>"; - qerror += "<p>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and " + qerror += "<p>" + i18n("The device <b>%1</b> (%2) named <b>'%3'</b> and " "currently mounted at <b>%4</b> could not be unmounted. ").arg( "system:/media/" + medium->name(), medium->deviceNode(), @@ -1504,7 +1669,6 @@ void TDEBackend::slotResult(TDEIO::Job *job) if (!proclist.isEmpty()) { qerror += proclist; } - qerror += "</qt>"; } else if (job->error()) { qerror = job->errorText(); } diff --git a/tdeioslave/media/mediamanager/tdehardwarebackend.h b/tdeioslave/media/mediamanager/tdehardwarebackend.h index 5c6ce1260..0c3f84410 100644 --- a/tdeioslave/media/mediamanager/tdehardwarebackend.h +++ b/tdeioslave/media/mediamanager/tdehardwarebackend.h @@ -44,7 +44,7 @@ class Dialog; class TDEBackend : public TQObject, public BackendBase { -Q_OBJECT +TQ_OBJECT public: /** @@ -68,11 +68,13 @@ public: bool setMountoptions(const TQString &id, const TQStringList &options); - TQStringVariantMap mount(const TQString &id); TQStringVariantMap mount(const Medium *medium); + TQStringVariantMap mount(const TQString &id); TQStringVariantMap unmount(const TQString &id); -// TQStringVariantMap unlock(const TQString &id, const TQString &password); -// TQStringVariantMap lock(const TQString &id); + TQStringVariantMap unlock(const TQString &id, const TQString &password); + TQStringVariantMap lock(const TQString &id, bool releaseHolders); + TQStringVariantMap eject(const TQString &id); + TQStringVariantMap safeRemove(const TQString &uid); private: /** @@ -103,9 +105,6 @@ private slots: void RemoveDeviceHandler(TDEGenericDevice* device); void ModifyDeviceHandler(TDEGenericDevice* device); - void slotPasswordReady(); - void slotPasswordCancel(); - signals: void signalDecryptionPasswordError(TQString); @@ -120,28 +119,19 @@ private: */ void ResetProperties(TDEStorageDevice * sdevice, bool allowNotification=false, bool overrideIgnoreList=false); - /** - * Find the medium that is concerned with device udi - */ -// const char* findMediumUdiFromUdi(const char* udi); - void setVolumeProperties(Medium* medium); bool setFloppyProperties(Medium* medium); - void setFloppyMountState( Medium* medium ); -// bool setFstabProperties(Medium* medium); + void setFloppyMountState(Medium* medium); void setCameraProperties(Medium* medium); + void releaseHolderDevices(const TQString &deviceNode, bool handleThis); TQString generateName(const TQString &devNode); + static TQString isInFstab(const Medium *medium); static TQString listUsingProcesses(const Medium *medium); static TQString killUsingProcesses(const Medium *medium); TQString driveUDIFromDeviceUID(TQString uuid); - // Decryption - Dialog* m_unlockDialog; - TQString m_decryptionPassword; - bool m_decryptPasswordValid; - private slots: void slotResult(TDEIO::Job *job); diff --git a/tdeioslave/media/medianotifier/CMakeLists.txt b/tdeioslave/media/medianotifier/CMakeLists.txt index ff2a8d802..215ee6de3 100644 --- a/tdeioslave/media/medianotifier/CMakeLists.txt +++ b/tdeioslave/media/medianotifier/CMakeLists.txt @@ -14,6 +14,7 @@ include_directories( ${CMAKE_BINARY_DIR}/tdeioslave/media/libmediacommon ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon ${CMAKE_SOURCE_DIR}/tdmlib + ${CMAKE_BINARY_DIR} ${TDE_INCLUDE_DIR} ${TQT_INCLUDE_DIRS} ) diff --git a/tdeioslave/media/medianotifier/medianotifier.cpp b/tdeioslave/media/medianotifier/medianotifier.cpp index 069e205de..2510019f2 100644 --- a/tdeioslave/media/medianotifier/medianotifier.cpp +++ b/tdeioslave/media/medianotifier/medianotifier.cpp @@ -19,14 +19,18 @@ #include "medianotifier.h" -#if defined (__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if defined (__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)\ + || defined(Q_OS_SOLARIS) +#ifdef Q_OS_SOLARIS +#include <sys/types.h> +#endif /* Q_OS_SOLARIS */ #include <sys/statvfs.h> #include <sys/param.h> #include <sys/mount.h> #else #include <sys/vfs.h> #endif -#if defined(__NetBSD__) +#if defined(__NetBSD__) || defined(Q_OS_SOLARIS) #define statfs statvfs #endif @@ -65,7 +69,7 @@ MediaNotifier::MediaNotifier(const TQCString &name) : KDEDModule(name) m_notificationDialogList.setAutoDelete(FALSE); m_freeTimer = new TQTimer( this ); - connect( m_freeTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( checkFreeDiskSpace() ) ); + connect( m_freeTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( checkFreeDiskSpace() ) ); m_freeTimer->start( 1000*6*2 /* 20 minutes */ ); m_freeDialog = 0; } @@ -119,8 +123,8 @@ void MediaNotifier::onMediumChange( const TQString &name, bool allowNotification m_allowNotificationMap[job] = allowNotification; - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotStatResult( TDEIO::Job * ) ) ); + connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ), + this, TQ_SLOT( slotStatResult( TDEIO::Job * ) ) ); } void MediaNotifier::slotStatResult( TDEIO::Job *job ) @@ -343,7 +347,7 @@ void MediaNotifier::notify( KFileItem &medium ) if ( actions.size()>1 ) { NotificationDialog* notifier = new NotificationDialog( medium, settings ); - connect(notifier, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(notificationDialogDestroyed(TQObject*))); + connect(notifier, TQ_SIGNAL(destroyed(TQObject*)), this, TQ_SLOT(notificationDialogDestroyed(TQObject*))); m_notificationDialogList.append(notifier); notifier->show(); } @@ -403,8 +407,8 @@ void MediaNotifier::checkFreeDiskSpace() i18n("Do not ask again"), &checkboxResult, KMessageBox::Notify | KMessageBox::NoExec); m_freeDialog->show(); - connect( m_freeDialog, TQT_SIGNAL( yesClicked() ), TQT_SLOT( slotFreeContinue() ) ); - connect( m_freeDialog, TQT_SIGNAL( noClicked() ), TQT_SLOT( slotFreeCancel() ) ); + connect( m_freeDialog, TQ_SIGNAL( yesClicked() ), TQ_SLOT( slotFreeContinue() ) ); + connect( m_freeDialog, TQ_SIGNAL( noClicked() ), TQ_SLOT( slotFreeCancel() ) ); } } } @@ -421,7 +425,7 @@ void MediaNotifier::slotFreeCancel() void MediaNotifier::slotFreeFinished( KMessageBox::ButtonCode res ) { - TQCheckBox *checkbox = ::tqqt_cast<TQCheckBox*>( m_freeDialog->child( 0, TQCHECKBOX_OBJECT_NAME_STRING ) ); + TQCheckBox *checkbox = ::tqt_cast<TQCheckBox*>( m_freeDialog->child( 0, "TQCheckBox" ) ); if ( checkbox && checkbox->isChecked() ) KMessageBox::saveDontShowAgainYesNo("dontagainfreespace", res); m_freeDialog->delayedDestruct(); diff --git a/tdeioslave/media/medianotifier/medianotifier.h b/tdeioslave/media/medianotifier/medianotifier.h index 84eee525c..c45db66c1 100644 --- a/tdeioslave/media/medianotifier/medianotifier.h +++ b/tdeioslave/media/medianotifier/medianotifier.h @@ -34,7 +34,7 @@ typedef TQPtrList<NotificationDialog> NotificationDialogList; class MediaNotifier: public KDEDModule { - Q_OBJECT + TQ_OBJECT K_DCOP public: diff --git a/tdeioslave/media/medianotifier/notificationdialog.cpp b/tdeioslave/media/medianotifier/notificationdialog.cpp index 7e4004e8c..a8bb81ea5 100644 --- a/tdeioslave/media/medianotifier/notificationdialog.cpp +++ b/tdeioslave/media/medianotifier/notificationdialog.cpp @@ -17,6 +17,10 @@ Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "notificationdialog.h" #include <tqlayout.h> @@ -28,7 +32,7 @@ #include <tqlabel.h> #include <tqcheckbox.h> #include <tqpushbutton.h> -#ifdef __TDE_HAVE_TDEHWLIB +#ifdef WITH_TDEHWLIB #include <tdehardwaredevices.h> #endif @@ -40,7 +44,7 @@ NotificationDialog::NotificationDialog( KFileItem medium, NotifierSettings *sett : KDialogBase( parent, name, false, i18n( "Medium Detected" ), Ok|Cancel|User1, Ok, true), m_medium(medium), m_settings( settings ) { - setCaption( TDEIO::decodeFileName(m_medium.name()) ); + setCaption( m_medium.text() ); clearWState( WState_Polished ); TQWidget *page = new TQWidget( this ); @@ -50,13 +54,14 @@ NotificationDialog::NotificationDialog( KFileItem medium, NotifierSettings *sett m_view = new NotificationDialogView( page ); topLayout->addWidget(m_view); - m_view->iconLabel->setPixmap( m_medium.pixmap(64) ); - m_view->mimetypeLabel->setText( i18n( "<b>Medium type:</b>" ) + " " - + m_medium.mimeTypePtr()->comment() ); + m_view->iconLabel->setPixmap(m_medium.pixmap(64)); + m_view->mimetypeLabel->setText(i18n("<b>Name:</b>") + "	" + m_medium.text() + "<br/>" + + i18n("<b>Type:</b>") + "	" + m_medium.mimeTypePtr()->comment() + "<br/>" + + i18n("<b>Url:</b>") + "	" + m_medium.url().prettyURL()); updateActionsListBox(); - resize( TQSize(400,400).expandedTo( minimumSizeHint() ) ); + resize( TQSize(500,500).expandedTo( minimumSizeHint() ) ); m_actionWatcher = new KDirWatch(); @@ -66,17 +71,17 @@ NotificationDialog::NotificationDialog( KFileItem medium, NotifierSettings *sett setButtonText( User1, i18n("Configure...") ); - connect( m_actionWatcher, TQT_SIGNAL( dirty( const TQString & ) ), - this, TQT_SLOT( slotActionsChanged( const TQString & ) ) ); - connect( this , TQT_SIGNAL( okClicked() ), - this, TQT_SLOT( slotOk() ) ); - connect( this, TQT_SIGNAL( user1Clicked() ), - this, TQT_SLOT( slotConfigure() ) ); - connect( m_view->actionsList, TQT_SIGNAL( doubleClicked ( TQListBoxItem*, const TQPoint & ) ), - this, TQT_SLOT( slotOk() ) ); - - connect( this, TQT_SIGNAL( finished() ), - this, TQT_SLOT( delayedDestruct() ) ); + connect( m_actionWatcher, TQ_SIGNAL( dirty( const TQString & ) ), + this, TQ_SLOT( slotActionsChanged( const TQString & ) ) ); + connect( this , TQ_SIGNAL( okClicked() ), + this, TQ_SLOT( slotOk() ) ); + connect( this, TQ_SIGNAL( user1Clicked() ), + this, TQ_SLOT( slotConfigure() ) ); + connect( m_view->actionsList, TQ_SIGNAL( doubleClicked ( TQListBoxItem*, const TQPoint & ) ), + this, TQ_SLOT( slotOk() ) ); + + connect( this, TQ_SIGNAL( finished() ), + this, TQ_SLOT( delayedDestruct() ) ); m_actionWatcher->startScan(); TQPushButton * btn = actionButton( Ok ); diff --git a/tdeioslave/media/medianotifier/notificationdialog.h b/tdeioslave/media/medianotifier/notificationdialog.h index 16bedb842..9f1f8057f 100644 --- a/tdeioslave/media/medianotifier/notificationdialog.h +++ b/tdeioslave/media/medianotifier/notificationdialog.h @@ -31,7 +31,7 @@ class NotificationDialog : public KDialogBase { - Q_OBJECT + TQ_OBJECT public: NotificationDialog( KFileItem medium, NotifierSettings *settings, diff --git a/tdeioslave/media/mimetypes/cd-r_encrypted_locked.desktop b/tdeioslave/media/mimetypes/cd-r_encrypted_locked.desktop index f4f288d10..50a23de70 100644 --- a/tdeioslave/media/mimetypes/cd-r_encrypted_locked.desktop +++ b/tdeioslave/media/mimetypes/cd-r_encrypted_locked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Locked CD-R Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cd-r_encrypted_unlocked.desktop b/tdeioslave/media/mimetypes/cd-r_encrypted_unlocked.desktop index 4826eddfa..c410a4e43 100644 --- a/tdeioslave/media/mimetypes/cd-r_encrypted_unlocked.desktop +++ b/tdeioslave/media/mimetypes/cd-r_encrypted_unlocked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Unlocked CD-R Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cd-rw_encrypted_locked.desktop b/tdeioslave/media/mimetypes/cd-rw_encrypted_locked.desktop index b5d3cabf0..5edac87e4 100644 --- a/tdeioslave/media/mimetypes/cd-rw_encrypted_locked.desktop +++ b/tdeioslave/media/mimetypes/cd-rw_encrypted_locked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Locked CD-RW Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cd-rw_encrypted_unlocked.desktop b/tdeioslave/media/mimetypes/cd-rw_encrypted_unlocked.desktop index c64bb19f8..6dd0de842 100644 --- a/tdeioslave/media/mimetypes/cd-rw_encrypted_unlocked.desktop +++ b/tdeioslave/media/mimetypes/cd-rw_encrypted_unlocked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Unlocked CD-RW Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdrom_encrypted_locked.desktop b/tdeioslave/media/mimetypes/cdrom_encrypted_locked.desktop index e5b7e80c9..6dc794dff 100644 --- a/tdeioslave/media/mimetypes/cdrom_encrypted_locked.desktop +++ b/tdeioslave/media/mimetypes/cdrom_encrypted_locked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Locked CD-ROM Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/cdrom_encrypted_unlocked.desktop b/tdeioslave/media/mimetypes/cdrom_encrypted_unlocked.desktop index 4731ffe4e..011228a88 100644 --- a/tdeioslave/media/mimetypes/cdrom_encrypted_unlocked.desktop +++ b/tdeioslave/media/mimetypes/cdrom_encrypted_unlocked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Unlocked CD-ROM Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_encrypted_locked.desktop b/tdeioslave/media/mimetypes/dvd_encrypted_locked.desktop index 0450a29ed..d4e3b25bd 100644 --- a/tdeioslave/media/mimetypes/dvd_encrypted_locked.desktop +++ b/tdeioslave/media/mimetypes/dvd_encrypted_locked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Locked DVD Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/dvd_encrypted_unlocked.desktop b/tdeioslave/media/mimetypes/dvd_encrypted_unlocked.desktop index 16e0a86a8..a4a66904a 100644 --- a/tdeioslave/media/mimetypes/dvd_encrypted_unlocked.desktop +++ b/tdeioslave/media/mimetypes/dvd_encrypted_unlocked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Unlocked DVD Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/hdd_encrypted_locked.desktop b/tdeioslave/media/mimetypes/hdd_encrypted_locked.desktop index 7de6c35cb..d4cc6d261 100644 --- a/tdeioslave/media/mimetypes/hdd_encrypted_locked.desktop +++ b/tdeioslave/media/mimetypes/hdd_encrypted_locked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Locked Hard Disk Volume Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/hdd_encrypted_unlocked.desktop b/tdeioslave/media/mimetypes/hdd_encrypted_unlocked.desktop index 9e944ef58..7c91927aa 100644 --- a/tdeioslave/media/mimetypes/hdd_encrypted_unlocked.desktop +++ b/tdeioslave/media/mimetypes/hdd_encrypted_unlocked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Unlocked Hard Disk Volume Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/removable_encrypted_locked.desktop b/tdeioslave/media/mimetypes/removable_encrypted_locked.desktop index 66671c168..d97745e12 100644 --- a/tdeioslave/media/mimetypes/removable_encrypted_locked.desktop +++ b/tdeioslave/media/mimetypes/removable_encrypted_locked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Locked Removable Medium Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mimetypes/removable_encrypted_unlocked.desktop b/tdeioslave/media/mimetypes/removable_encrypted_unlocked.desktop index 94e81353b..fd98df9c0 100644 --- a/tdeioslave/media/mimetypes/removable_encrypted_unlocked.desktop +++ b/tdeioslave/media/mimetypes/removable_encrypted_unlocked.desktop @@ -9,4 +9,3 @@ Comment=Encrypted Unlocked Removable Medium Patterns= X-TDE-AutoEmbed=true -X-TDE-IsAlso=inode/directory diff --git a/tdeioslave/media/mounthelper/CMakeLists.txt b/tdeioslave/media/mounthelper/CMakeLists.txt index 90afad33f..cf7ca553f 100644 --- a/tdeioslave/media/mounthelper/CMakeLists.txt +++ b/tdeioslave/media/mounthelper/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_BINARY_DIR} ${TDE_INCLUDE_DIR} ${TQT_INCLUDE_DIRS} ) @@ -31,6 +32,6 @@ set( ${target}_SRCS tde_add_executable( ${target} AUTOMOC SOURCES ${${target}_SRCS} - LINK mediacommon-static tdeio-shared + LINK mediacommon-static tdeio-shared ${TDEHW_LIBRARIES} DESTINATION ${BIN_INSTALL_DIR} ) diff --git a/tdeioslave/media/mounthelper/dialog.cpp b/tdeioslave/media/mounthelper/dialog.cpp index f2cdb6b53..a257ca6d8 100644 --- a/tdeioslave/media/mounthelper/dialog.cpp +++ b/tdeioslave/media/mounthelper/dialog.cpp @@ -23,11 +23,10 @@ #include "dialog.h" Dialog::Dialog(TQString url, TQString iconName) : - KDialogBase(NULL, "Dialog", true, "Unlock Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Unlock"), "unlocked" )) + KDialogBase(NULL, "Dialog", true, i18n("Unlock Storage Device"), (Cancel|User1), User1, false, KGuiItem(i18n("Unlock"), "unlocked" )) { unlockDialog = new UnlockDialog(this); - unlockDialog->errorBox->hide(); unlockDialog->descLabel->setText(unlockDialog->descLabel->text().arg(url)); unlockDialog->descLabel->adjustSize(); unlockDialog->adjustSize(); @@ -37,7 +36,7 @@ Dialog::Dialog(TQString url, TQString iconName) : TQPixmap pixmap = TDEGlobal::iconLoader()->loadIcon(iconName, TDEIcon::NoGroup, TDEIcon::SizeLarge); unlockDialog->encryptedIcon->setPixmap( pixmap ); - connect(unlockDialog->passwordEdit, TQT_SIGNAL (textChanged(const TQString &)), this, TQT_SLOT (slotPasswordChanged(const TQString &))); + connect(unlockDialog->passwordEdit, TQ_SIGNAL (textChanged(const TQString &)), this, TQ_SLOT (slotPasswordChanged(const TQString &))); setMainWidget(unlockDialog); } @@ -52,14 +51,6 @@ TQString Dialog::getPassword() return unlockDialog->passwordEdit->text(); } -void Dialog::slotDialogError(TQString errorMsg) -{ - kdDebug() << __func__ << "(" << errorMsg << " )" << endl; - - unlockDialog->errorLabel->setText(TQString("<b>%1</b>").arg(errorMsg)); - unlockDialog->errorBox->show(); -} - void Dialog::slotPasswordChanged(const TQString &text) { enableButton( User1, !text.isEmpty() ); diff --git a/tdeioslave/media/mounthelper/dialog.h b/tdeioslave/media/mounthelper/dialog.h index 8444ec7dd..d2b2925a9 100644 --- a/tdeioslave/media/mounthelper/dialog.h +++ b/tdeioslave/media/mounthelper/dialog.h @@ -36,12 +36,10 @@ #include "unlockdialog.h" -class KryptoMedia; - class Dialog : public KDialogBase { -Q_OBJECT +TQ_OBJECT public: Dialog(TQString url, TQString iconName); @@ -50,7 +48,6 @@ public: TQString getPassword(); public slots: - void slotDialogError(TQString errorMsg); void slotPasswordChanged(const TQString &text); private: diff --git a/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp index 65b53a0f4..90f3caa3f 100644 --- a/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp +++ b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp @@ -19,6 +19,10 @@ Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <tdecmdlineargs.h> #include <tdelocale.h> #include <tdeapplication.h> @@ -33,223 +37,238 @@ #include <kprocess.h> #include <tdestartupinfo.h> #include <kmimetype.h> -#ifdef __TDE_HAVE_TDEHWLIB +#ifdef WITH_TDEHWLIB #include <tdehardwaredevices.h> #endif #include "dialog.h" #include "tdeio_media_mounthelper.h" -const Medium MountHelper::findMedium(const KURL &url) +const Medium MountHelper::findMedium(const TQString &device) { DCOPRef mediamanager("kded", "mediamanager"); - - // Try filename first - DCOPReply reply = mediamanager.call( "properties", url.fileName() ); - if ( !reply.isValid() ) { - m_errorStr = i18n("The TDE mediamanager is not running.")+"\n"; + DCOPReply reply = mediamanager.call("properties", device); + if (!reply.isValid()) + { + m_errorStr = i18n("The TDE mediamanager is not running.\n"); return Medium(TQString::null, TQString::null, TQString::null); } - const Medium& medium = Medium::create(reply); - if ( medium.id().isEmpty() ) { - // Try full URL now - reply = mediamanager.call( "properties", url.prettyURL() ); - if ( !reply.isValid() ) { - m_errorStr = i18n("Internal Error"); - return Medium(TQString::null, TQString::null, TQString::null); - } - return Medium::create(reply); - } else { - return medium; - } + const Medium &medium = Medium::create(reply); + return medium; } -MountHelper::MountHelper() : TDEApplication() +void MountHelper::mount(const Medium &medium) { - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call("mount", medium.id()); + TQStringVariantMap mountResult; + if (reply.isValid()) { + reply.get(mountResult); + } + if (!mountResult.contains("result") || !mountResult["result"].toBool()) { + m_errorStr = mountResult.contains("errStr") ? mountResult["errStr"].toString() : i18n("Unknown mount error."); + errorAndExit(); + } +} - m_errorStr = TQString::null; +void MountHelper::unmount(const Medium &medium) +{ + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call("unmount", medium.id()); + TQStringVariantMap unmountResult; + if (reply.isValid()) { + reply.get(unmountResult); + } + if (!unmountResult.contains("result") || !unmountResult["result"].toBool()) { + m_errorStr = unmountResult.contains("errStr") ? unmountResult["errStr"].toString() : i18n("Unknown unmount error."); + kdDebug() << "medium unmount " << m_errorStr << endl; + errorAndExit(); + } +} - KURL url(args->url(0)); - const Medium medium = findMedium(url); +void MountHelper::unlock(const Medium &medium) +{ + TQString device = medium.deviceNode(); + if (device.isEmpty()) { + m_errorStr = i18n("Try to unlock an unknown medium."); + errorAndExit(); + } - if (medium.id().isEmpty()) + TQString iconName = medium.iconName(); + if (iconName.isEmpty()) { - if (m_errorStr.isEmpty()) { - m_errorStr+= i18n("%1 cannot be found.").arg(url.prettyURL()); - } - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; + TQString mime = medium.mimeType(); + iconName = KMimeType::mimeType(mime)->icon(mime, false); } + m_mediumId = medium.id(); + m_dialog = new Dialog(device, iconName); + connect(m_dialog, TQ_SIGNAL(user1Clicked()), this, TQ_SLOT(slotSendPassword())); + connect(m_dialog, TQ_SIGNAL(cancelClicked()), this, TQ_SLOT(slotCancel())); + m_dialog->show(); +} - if (!medium.isMountable() && !args->isSet("e") && !args->isSet("s")) +void MountHelper::lock(const Medium &medium) +{ + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call("lock", medium.id(), true); + TQStringVariantMap lockResult; + if (reply.isValid()) { + reply.get(lockResult); + } + if (!lockResult.contains("result") || !lockResult["result"].toBool()) { + m_errorStr = lockResult.contains("errStr") ? lockResult["errStr"].toString() : i18n("Unknown lock error."); + kdDebug() << "medium lock " << m_errorStr << endl; + errorAndExit(); + } +} + +void MountHelper::eject(const Medium &medium) +{ +#ifdef WITH_TDEHWLIB + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call("eject", medium.id()); + TQStringVariantMap ejectResult; + if (reply.isValid()) { + reply.get(ejectResult); + } + if (!ejectResult.contains("result") || !ejectResult["result"].toBool()) { + m_errorStr = ejectResult.contains("errStr") ? ejectResult["errStr"].toString() : i18n("Unknown eject error."); + kdDebug() << "medium eject " << m_errorStr << endl; + errorAndExit(); + } + else { - m_errorStr = i18n("%1 is not a mountable media.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; + ::exit(0); // Success! } +#endif - TQString device = medium.deviceNode(); - TQString mount_point = medium.mountPoint(); + // Otherwise fall back to tdeeject + TDEProcess *proc = new TDEProcess(this); + *proc << "tdeeject"; + *proc << medium.deviceNode(); + connect(proc, TQ_SIGNAL(processExited(TDEProcess*)), this, TQ_SLOT(ejectFinished(TDEProcess*))); + proc->start(); +} + +void MountHelper::safeRemoval(const Medium &medium) +{ + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call("safeRemove", medium.id()); + TQStringVariantMap safeRemoveResult; + if (reply.isValid()) { + reply.get(safeRemoveResult); + } + if (!safeRemoveResult.contains("result") || !safeRemoveResult["result"].toBool()) { + m_errorStr = safeRemoveResult.contains("errStr") ? safeRemoveResult["errStr"].toString() : i18n("Unknown safe removal error."); + kdDebug() << "medium safeRemoval " << m_errorStr << endl; + errorAndExit(); + } +} - m_isCdrom = medium.mimeType().find("dvd") != -1 || medium.mimeType().find("cd") != -1; +void MountHelper::openRealFolder(const Medium &medium) +{ + Medium &m = const_cast<Medium&>(medium); + if (!m.isMounted()) + { + // If the medium is not mounted, try mounting it first + mount(m); + m = findMedium(m.deviceNode()); + } - if (args->isSet("d")) + if (m.isMounted()) { - if (!medium.isEncrypted()) - { - m_errorStr = i18n("%1 is not an encrypted media.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; - } - if (!medium.needDecryption()) - { - m_errorStr = i18n("%1 is already unlocked.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error())); - return; - } + system((TQString("kfmclient exec 'file://") + m.mountPoint()).local8Bit() + "'"); + } + else + { + m_errorStr = i18n("Try to open an unknown medium."); + errorAndExit(); + } +} - TQString iconName = medium.iconName(); - if (iconName.isEmpty()) - { - TQString mime = medium.mimeType(); - iconName = KMimeType::mimeType(mime)->icon(mime, false); +MountHelper::MountHelper() : TDEApplication() +{ + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + m_errorStr = TQString::null; + + const Medium medium = findMedium(args->arg(0)); + if (medium.id().isEmpty()) + { + if (m_errorStr.isEmpty()) { + m_errorStr+= i18n("%1 cannot be found.").arg(args->arg(0)); } + errorAndExit(); + } - m_mediumId = medium.id(); - dialog = new Dialog(url.prettyURL(), iconName); - dialog->show(); + TQString device = medium.deviceNode(); + if (!medium.isMountable() && !medium.isEncrypted() && !args->isSet("e") && !args->isSet("s")) + { + m_errorStr = i18n("%1 is not a mountable or encrypted media.").arg(device); + errorAndExit(); + } - connect(dialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotSendPassword())); - connect(dialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotCancel())); - connect(this, TQT_SIGNAL (signalPasswordError(TQString)), dialog, TQT_SLOT (slotDialogError(TQString))); + if (args->isSet("m")) + { + mount(medium); + ::exit(0); } else if (args->isSet("u")) { - DCOPRef mediamanager("kded", "mediamanager"); - DCOPReply reply = mediamanager.call("unmount", medium.id()); - TQStringVariantMap unmountResult; - if (reply.isValid()) { - reply.get(unmountResult); - } - if (unmountResult.contains("result") && unmountResult["result"].toBool()) { - ::exit(0); - } - else { - m_errorStr = unmountResult.contains("errStr") ? unmountResult["errStr"].toString() : i18n("Unknown unmount error."); - kdDebug() << "medium unmount " << m_errorStr << endl; - error(); - } - } - else if (args->isSet("s") || args->isSet("e")) + unmount(medium); + ::exit(0); + } + else if (args->isSet("k")) { - DCOPRef mediamanager("kded", "mediamanager"); - - /* - * We want to call mediamanager unmount before invoking eject. That's - * because unmount would provide an informative error message in case of - * failure. However, there are cases when unmount would fail - * (supermount, slackware, see bug#116209) but eject would succeed. - * Thus if unmount fails, save unmount error message and invokeEject() - * anyway. Only if both unmount and eject fail, notify the user by - * displaying the saved error message (see ejectFinished()). - */ - TQStringVariantMap unmountResult; - if (medium.isMounted()) - { - DCOPReply reply = mediamanager.call( "unmount", medium.id()); - if (reply.isValid()) { - reply.get(unmountResult); - if (unmountResult["result"].toBool()) { - reply.get(m_errorStr); - } - } - } - - // If this is an unlocked encrypted volume and there is no error yet, we try to lock it - if (unmountResult.contains("result") && unmountResult["result"].toBool() && - medium.isEncrypted() && !medium.clearDeviceUdi().isNull()) - { - DCOPReply reply = mediamanager.call( "undecrypt", medium.id()); - if (reply.isValid()) { - TQStringVariantMap undecryptResult; - reply.get(undecryptResult); - if (undecryptResult["result"].toBool()) { - reply.get(m_errorStr); - } - } - } - - if (m_errorStr.isNull()) { - invokeEject(device, true); - } - else { - error(); - } + unlock(medium); + // No call to ::exit() here because this will open up the password dialog + // ::exit() is handled in the invoked code. + } + else if (args->isSet("l")) + { + lock(medium); + ::exit(0); + } + else if (args->isSet("e")) + { + eject(medium); + ::exit(0); + } + else if (args->isSet("s")) + { + safeRemoval(medium); + ::exit(0); + } + else if (args->isSet("f")) + { + openRealFolder(medium); + ::exit(0); } else { - DCOPRef mediamanager("kded", "mediamanager"); - DCOPReply reply = mediamanager.call("mount", medium.id()); - TQStringVariantMap mountResult; - if (reply.isValid()) { - reply.get(mountResult); - } - if (mountResult.contains("result") && mountResult["result"].toBool()) { - ::exit(0); - } - else { - m_errorStr = mountResult.contains("errStr") ? mountResult["errStr"].toString() : i18n("Unknown mount error."); - error(); - } + TDECmdLineArgs::usage(); + ::exit(0); } } -void MountHelper::invokeEject(const TQString &device, bool quiet) +MountHelper::~MountHelper() { -#ifdef __TDE_HAVE_TDEHWLIB - // Try TDE HW library eject first... - TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); - TDEGenericDevice *hwdevice = hwdevices->findByDeviceNode(device); - if (hwdevice->type() == TDEGenericDeviceType::Disk) { - TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice); - if (sdevice->ejectDrive()) { - // Success! - ::exit(0); - } - } -#endif - - // Then fall back to tdeeject if needed - TDEProcess *proc = new TDEProcess(TQT_TQOBJECT(this)); - *proc << "tdeeject"; - if (quiet) + if (m_dialog) { - *proc << "-q"; + delete m_dialog; } - *proc << device; - connect( proc, TQT_SIGNAL(processExited(TDEProcess *)), - this, TQT_SLOT( ejectFinished(TDEProcess *) ) ); - proc->start(); } -void MountHelper::ejectFinished(TDEProcess* proc) +void MountHelper::ejectFinished(TDEProcess *proc) { - /* - * If eject failed, report the error stored in m_errorStr - */ + //If eject failed, report the error stored in m_errorStr if (proc->normalExit() && proc->exitStatus() == 0) { ::exit(0); - } else { - if (m_errorStr.isEmpty()) { - if (m_isCdrom) - m_errorStr = i18n("The device was successfully unmounted, but the tray could not be opened"); - else - m_errorStr = i18n("The device was successfully unmounted, but could not be ejected"); + } + else { + if (!m_errorStr.isEmpty()) { + errorAndExit(); } -//X Comment this because the error is useless as long as the unmount is successful. -//X TQTimer::singleShot(0, this, TQT_SLOT(error())); - ::exit(0); + ::exit(0); } } @@ -262,25 +281,28 @@ void MountHelper::error() } } KMessageBox::error(0, prettyErrorString); +} + +void MountHelper::errorAndExit() +{ + error(); ::exit(1); } void MountHelper::slotSendPassword() { DCOPRef mediamanager("kded", "mediamanager"); - - DCOPReply reply = mediamanager.call( "decrypt", m_mediumId, dialog->getPassword() ); - TQStringVariantMap decryptResult; + DCOPReply reply = mediamanager.call("unlock", m_mediumId, m_dialog->getPassword()); + TQStringVariantMap unlockResult; if (reply.isValid()) { - reply.get(decryptResult); + reply.get(unlockResult); } - if (decryptResult.contains("result") && decryptResult["result"].toBool()) { + if (unlockResult.contains("result") && unlockResult["result"].toBool()) { ::exit(0); } else { - m_errorStr = decryptResult.contains("errStr") ? decryptResult["errStr"].toString() : i18n("Unknown decrypt error."); - kdDebug() << "medium decrypt " << m_errorStr << endl; - emit signalPasswordError(m_errorStr); + m_errorStr = unlockResult.contains("errStr") ? unlockResult["errStr"].toString() : i18n("Unknown unlock error."); + kdDebug() << "medium unlock " << m_errorStr << endl; error(); } } @@ -292,12 +314,14 @@ void MountHelper::slotCancel() static TDECmdLineOptions options[] = { - { "d", I18N_NOOP("Decrypt given URL"), 0 }, + { "m", I18N_NOOP("Mount given URL"), 0 }, { "u", I18N_NOOP("Unmount given URL"), 0 }, - { "m", I18N_NOOP("Mount given URL (default)"), 0 }, - { "e", I18N_NOOP("Eject given URL via tdeeject"), 0}, - { "s", I18N_NOOP("Unmount and Eject given URL (necessary for some USB devices)"), 0}, - {"!+URL", I18N_NOOP("media:/ URL to mount/unmount/eject/remove"), 0 }, + { "k", I18N_NOOP("Unlock given URL"), 0 }, + { "l", I18N_NOOP("Lock given URL"), 0 }, + { "e", I18N_NOOP("Eject given URL"), 0}, + { "s", I18N_NOOP("Safely remove (unmount and eject) given URL"), 0}, + { "f", I18N_NOOP("Open real medium folder"), 0}, + {"!+URL", I18N_NOOP("media:/URL to mount/unmount/unlock/lock/eject/remove"), 0 }, TDECmdLineLastOption }; @@ -308,13 +332,15 @@ int main(int argc, char **argv) "tdeio_media_mounthelper", "tdeio_media_mounthelper", "0.1"); - TDECmdLineArgs::addCmdLineOptions( options ); + TDECmdLineArgs::addCmdLineOptions(options); TDEGlobal::locale()->setMainCatalogue("tdeio_media"); TDEApplication::addCmdLineOptions(); + if (TDECmdLineArgs::parsedArgs()->count()==0) + { + TDECmdLineArgs::usage(); + } - if (TDECmdLineArgs::parsedArgs()->count()==0) TDECmdLineArgs::usage(); - TDEApplication *app = new MountHelper(); - + TDEApplication *app = new MountHelper(); TDEStartupInfo::appStarted(); app->dcopClient()->attach(); return app->exec(); diff --git a/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h index 97df6b7e8..3cdf58488 100644 --- a/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h +++ b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> + Copyright (c) 2004 Kévin Ottens <ervin ipsquad net> Parts of this file are Copyright 2003 Waldo Bastian <bastian@kde.org> @@ -29,29 +29,37 @@ #include "medium.h" class Dialog; +class TDEProcess; class MountHelper : public TDEApplication { - Q_OBJECT + TQ_OBJECT + public: MountHelper(); + ~MountHelper(); private: - const Medium findMedium(const KURL &url); - void invokeEject(const TQString &device, bool quiet=false); TQString m_errorStr; - bool m_isCdrom; TQString m_mediumId; - Dialog *dialog; + Dialog *m_dialog; + + const Medium findMedium(const TQString &device); + void error(); + + void mount(const Medium &medium); + void unmount(const Medium &medium); + void unlock(const Medium &medium); + void lock(const Medium &medium); + void eject(const Medium &medium); + void safeRemoval(const Medium &medium); + void openRealFolder(const Medium &medium); private slots: void slotSendPassword(); void slotCancel(); void ejectFinished(TDEProcess* proc); - void error(); - -signals: - void signalPasswordError(TQString errorMsg); + void errorAndExit(); }; #endif diff --git a/tdeioslave/media/mounthelper/unlockdialog.ui b/tdeioslave/media/mounthelper/unlockdialog.ui index 99a46a9ac..7b78cdb42 100644 --- a/tdeioslave/media/mounthelper/unlockdialog.ui +++ b/tdeioslave/media/mounthelper/unlockdialog.ui @@ -107,7 +107,7 @@ </property> <property name="text"> <string><p><b>%1</b> is an encrypted storage device.</p> -<p>Please enter the password to decrypt the storage device.</p></string> +<p>Please enter the password to unlock the storage device.</p></string> </property> <property name="alignment"> <set>WordBreak|AlignTop</set> @@ -155,46 +155,6 @@ </widget> </hbox> </widget> - <widget class="TQGroupBox" row="2" column="0"> - <property name="name"> - <cstring>errorBox</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>3</hsizetype> - <vsizetype>3</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Error</string> - </property> - <grid> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="TQLabel" row="0" column="0"> - <property name="name"> - <cstring>errorLabel</cstring> - </property> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>3</hsizetype> - <vsizetype>3</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string></string> - </property> - <property name="alignment"> - <set>WordBreak|AlignTop</set> - </property> - </widget> - </grid> - </widget> </grid> </widget> <layoutdefaults spacing="6" margin="11"/> diff --git a/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop b/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop index bd5ece69c..8d460d565 100644 --- a/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop +++ b/tdeioslave/media/propsdlgplugin/media_propsdlgplugin.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Type=Service X-TDE-Library=media_propsdlgplugin -X-TDE-ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/blankcd,media/blankbluray,media/blankdvd,media/hdd_mounted,media/hdd_unmounted,media/hdd_encrypted_unlocked,media/bluray_mounted,media/bluray_unmounted,media/bluray_encrypted_unlocked,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_encrypted_unlocked,media/cd-r_mounted,media/cd-r_unmounted,media/cd-r_encrypted_unlocked,media/cd-rw_mounted,media/cd-rw_unmounted,media/cd-rw_encrypted_unlocked,media/dvd_mounted,media/dvd_unmounted,media/dvd_encrypted_unlocked,media/removable_mounted,media/removable_unmounted,media/removable_encrypted_unlocked,media/nfs_mounted,media/nfs_unmounted,media/smb_mounted,media/smb_unmounted,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd,media/floppy_mounted,media/floppy_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/zip_mounted,media/zip_unmounted,media/gphoto2camera,media/camera_mounted,media/camera_unmounted +X-TDE-ServiceTypes=KPropsDlg/Plugin,media/audiocd,media/blankcd,media/blankbluray,media/blankdvd,media/hdd_mounted,media/hdd_unmounted,media/bluray_mounted,media/bluray_unmounted,media/cdrom_mounted,media/cdrom_unmounted,media/cd-r_mounted,media/cd-r_unmounted,media/cd-rw_mounted,media/cd-rw_unmounted,media/dvd_mounted,media/dvd_unmounted,media/removable_mounted,media/removable_unmounted,media/nfs_mounted,media/nfs_unmounted,media/smb_mounted,media/smb_unmounted,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd,media/floppy_mounted,media/floppy_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/zip_mounted,media/zip_unmounted,media/gphoto2camera,media/camera_mounted,media/camera_unmounted Name=Media Properties Page diff --git a/tdeioslave/media/propsdlgplugin/propertiespage.cpp b/tdeioslave/media/propsdlgplugin/propertiespage.cpp index 5b54c8c5a..57fff8573 100644 --- a/tdeioslave/media/propsdlgplugin/propertiespage.cpp +++ b/tdeioslave/media/propsdlgplugin/propertiespage.cpp @@ -64,43 +64,43 @@ PropertiesPage::PropertiesPage(TQWidget* parent, const TQString &_id) option_ro->hide(); else option_ro->setChecked(options["ro"] == "true"); - connect( option_ro, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_ro, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("quiet")) option_quiet->hide(); else option_quiet->setChecked(options["quiet"] == "true"); - connect( option_quiet, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_quiet, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("sync")) option_sync->hide(); else option_sync->setChecked(options["sync"] == "true"); - connect( option_sync, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_sync, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("atime")) option_atime->hide(); else option_atime->setChecked(options["atime"] == "true"); - connect( option_atime, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_atime, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("flush")) option_flush->hide(); else option_flush->setChecked(options["flush"] == "true"); - connect( option_flush, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_flush, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("utf8")) option_utf8->hide(); else option_utf8->setChecked(options["utf8"] == "true"); - connect( option_utf8, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_utf8, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("uid")) option_uid->hide(); else option_uid->setChecked(options["uid"] == "true"); - connect( option_uid, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_uid, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); if (!options.contains("shortname")) { @@ -115,7 +115,7 @@ PropertiesPage::PropertiesPage(TQWidget* parent, const TQString &_id) option_shortname->setCurrentItem(index); break; } - connect( option_shortname, TQT_SIGNAL( activated(int) ), TQT_SIGNAL( changed() ) ); + connect( option_shortname, TQ_SIGNAL( activated(int) ), TQ_SIGNAL( changed() ) ); } if (!options.contains("journaling")) @@ -131,14 +131,14 @@ PropertiesPage::PropertiesPage(TQWidget* parent, const TQString &_id) option_journaling->setCurrentItem(index); break; } - connect( option_journaling, TQT_SIGNAL( activated(int) ), TQT_SIGNAL( changed() ) ); + connect( option_journaling, TQ_SIGNAL( activated(int) ), TQ_SIGNAL( changed() ) ); } label_filesystem->setText(i18n("Filesystem: %1").arg(options["filesystem"])); option_mountpoint->setText(options["mountpoint"]); - connect( option_mountpoint, TQT_SIGNAL( textChanged( const TQString &) ), TQT_SIGNAL( changed() ) ); + connect( option_mountpoint, TQ_SIGNAL( textChanged( const TQString &) ), TQ_SIGNAL( changed() ) ); option_automount->setChecked(options["automount"] == "true"); - connect( option_automount, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_automount, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); bool has_groupbox_specific = true; if (!options.contains("journaling") && @@ -152,11 +152,11 @@ PropertiesPage::PropertiesPage(TQWidget* parent, const TQString &_id) // The order is important - we want groupboxes to hide automatically depending on use_defaults // but don't want to emit changed() until user actually changes something. - connect( option_defaults, TQT_SIGNAL( toggled(bool) ), groupbox_generic, SLOT( setHidden(bool) ) ); + connect( option_defaults, TQ_SIGNAL( toggled(bool) ), groupbox_generic, TQ_SLOT( setHidden(bool) ) ); if (has_groupbox_specific) - connect( option_defaults, TQT_SIGNAL( toggled(bool) ), groupbox_specific, SLOT( setHidden(bool) ) ); + connect( option_defaults, TQ_SIGNAL( toggled(bool) ), groupbox_specific, TQ_SLOT( setHidden(bool) ) ); option_defaults->setChecked(options["use_defaults"] == "true"); - connect( option_defaults, TQT_SIGNAL( stateChanged(int) ), TQT_SIGNAL( changed() ) ); + connect( option_defaults, TQ_SIGNAL( stateChanged(int) ), TQ_SIGNAL( changed() ) ); } else { diff --git a/tdeioslave/media/propsdlgplugin/propertiespage.h b/tdeioslave/media/propsdlgplugin/propertiespage.h index 50a480719..33baef40f 100644 --- a/tdeioslave/media/propsdlgplugin/propertiespage.h +++ b/tdeioslave/media/propsdlgplugin/propertiespage.h @@ -28,7 +28,7 @@ class Medium; class PropertiesPage : public PropertiesPageGUI { - Q_OBJECT + TQ_OBJECT public: PropertiesPage(TQWidget* parent, const TQString &_id); diff --git a/tdeioslave/media/propsdlgplugin/propertiespagegui.ui b/tdeioslave/media/propsdlgplugin/propertiespagegui.ui index 2a6ff899e..5d461b406 100644 --- a/tdeioslave/media/propsdlgplugin/propertiespagegui.ui +++ b/tdeioslave/media/propsdlgplugin/propertiespagegui.ui @@ -372,12 +372,12 @@ Display the short name as is; store a long name when the short name is not all u <variables> <variable>bool m_hasChanged;</variable> </variables> -<Q_SIGNALS> +<signals> <signal>changed()</signal> -</Q_SIGNALS> -<Q_SLOTS> +</signals> +<slots> <slot access="protected">changedSlot()</slot> -</Q_SLOTS> +</slots> <functions> <function returnType="bool">hasChanged()</function> </functions> diff --git a/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp index ea830d2e1..dce33d786 100644 --- a/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp +++ b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.cpp @@ -70,10 +70,10 @@ PropsDlgSharePlugin::PropsDlgSharePlugin( KPropertiesDialog *dlg, d = new Private(); d->page = new PropertiesPage(vbox, Medium::create(reply).id()); - connect(d->page, TQT_SIGNAL(changed()), - TQT_SLOT(slotChanged())); + connect(d->page, TQ_SIGNAL(changed()), + TQ_SLOT(slotChanged())); - // TQTimer::singleShot(100, this, TQT_SLOT(slotChanged())); + // TQTimer::singleShot(100, this, TQ_SLOT(slotChanged())); } diff --git a/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h index 87b7d1e13..e2ed740a7 100644 --- a/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h +++ b/tdeioslave/media/propsdlgplugin/propsdlgshareplugin.h @@ -24,7 +24,7 @@ class PropsDlgSharePlugin : public KPropsDlgPlugin { -Q_OBJECT +TQ_OBJECT public: PropsDlgSharePlugin( KPropertiesDialog *dlg, const char *, const TQStringList & ); virtual ~PropsDlgSharePlugin(); diff --git a/tdeioslave/media/services/CMakeLists.txt b/tdeioslave/media/services/CMakeLists.txt index b550409ba..932188725 100644 --- a/tdeioslave/media/services/CMakeLists.txt +++ b/tdeioslave/media/services/CMakeLists.txt @@ -13,8 +13,10 @@ tde_create_translated_desktop( SOURCE - media_decrypt.desktop media_mount.desktop media_unmount.desktop + media_mount.desktop media_unmount.desktop + media_unlock.desktop media_lock.desktop media_eject.desktop media_safelyremove.desktop + media_realfolder.desktop DESTINATION ${DATA_INSTALL_DIR}/konqueror/servicemenus PO_DIR tdeioslave-desktops ) diff --git a/tdeioslave/media/services/Makefile.am b/tdeioslave/media/services/Makefile.am index c744934f2..e08b06be8 100644 --- a/tdeioslave/media/services/Makefile.am +++ b/tdeioslave/media/services/Makefile.am @@ -1,3 +1,3 @@ servicesdir = $(kde_datadir)/konqueror/servicemenus -services_DATA = media_decrypt.desktop media_mount.desktop media_unmount.desktop media_eject.desktop media_safelyremove.desktop +services_DATA = media_mount.desktop media_unmount.desktop media_unlock.desktop media_lock.desktop media_eject.desktop media_safelyremove.desktop media_realfolder.desktop diff --git a/tdeioslave/media/services/media_decrypt.desktop b/tdeioslave/media/services/media_decrypt.desktop deleted file mode 100644 index ee48f2e63..000000000 --- a/tdeioslave/media/services/media_decrypt.desktop +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -X-TDE-ServiceTypes=media/removable_encrypted_locked,media/hdd_encrypted_locked,media/bluray_encrypted_locked,media/cdrom_encrypted_locked,media/cd-r_encrypted_locked,media/cd-rw_encrypted_locked,media/dvd_encrypted_locked -Actions=MediaUnlock; -X-TDE-Priority=TopLevel -X-TDE-MediaNotifierHide=true - -[Desktop Action MediaUnlock] -Name=Unlock - -Exec=tdeio_media_mounthelper -k %u -Icon=decrypted diff --git a/tdeioslave/media/services/media_eject.desktop b/tdeioslave/media/services/media_eject.desktop index ad289fd33..0bb128656 100644 --- a/tdeioslave/media/services/media_eject.desktop +++ b/tdeioslave/media/services/media_eject.desktop @@ -1,10 +1,10 @@ [Desktop Entry] -X-TDE-ServiceTypes=media/bluray_mounted,media/bluray_unmounted,media/bluray_encrypted_unlocked,media/bluray_encrypted_locked,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_encrypted_unlocked,media/cdrom_encrypted_locked,media/cd-r_mounted,media/cd-r_unmounted,media/cd-r_encrypted_unlocked,media/cd-r_encrypted_locked,media/cd-rw_mounted,media/cd-rw_unmounted,media/cd-rw_encrypted_unlocked,media/cd-rw_encrypted_locked,media/dvd_mounted,media/dvd_unmounted,media/dvd_encrypted_unlocked,media/dvd_encrypted_locked,media/audiocd,media/blankbluray,media/blankcd,media/blankdvd,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd +X-TDE-ServiceTypes=media/bluray_mounted,media/bluray_unmounted,media/bluray_encrypted_locked,media/bluray_encrypted_unlocked,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_encrypted_locked,media/cdrom_encrypted_unlocked,media/cd-r_mounted,media/cd-r_unmounted,media/cd-r_encrypted_locked,media/cd-r_encrypted_unlocked,media/cd-rw_mounted,media/cd-rw_unmounted,media/cd-rw_encrypted_locked,media/cd-rw_encrypted_unlocked,media/dvd_mounted,media/dvd_unmounted,media/dvd_encrypted_locked,media/dvd_encrypted_unlocked,media/audiocd,media/blankbluray,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd Actions=MediaEject; X-TDE-Priority=TopLevel X-TDE-MediaNotifierHide=true [Desktop Action MediaEject] -Name=Eject - Exec=tdeio_media_mounthelper -e %u +Icon=player_eject +Name=Eject diff --git a/tdeioslave/media/services/media_lock.desktop b/tdeioslave/media/services/media_lock.desktop new file mode 100644 index 000000000..d57565312 --- /dev/null +++ b/tdeioslave/media/services/media_lock.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +X-TDE-ServiceTypes=media/bluray_encrypted_unlocked,media/cdrom_encrypted_unlocked,media/cd-r_encrypted_unlocked,media/cd-rw_encrypted_unlocked,media/dvd_encrypted_unlocked,media/hdd_encrypted_unlocked,media/removable_encrypted_unlocked +Actions=MediaLock; +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=true + +[Desktop Action MediaLock] +Exec=tdeio_media_mounthelper -l %u +Icon=encrypted +Name=Lock diff --git a/tdeioslave/media/services/media_mount.desktop b/tdeioslave/media/services/media_mount.desktop index d0f164bb9..f018cfd18 100644 --- a/tdeioslave/media/services/media_mount.desktop +++ b/tdeioslave/media/services/media_mount.desktop @@ -1,10 +1,10 @@ [Desktop Entry] -X-TDE-ServiceTypes=media/bluray_unmounted,media/bluray_encrypted_unlocked,media/cdrom_unmounted,media/cdrom_encrypted_unlocked,media/cd-r_unmounted,media/cd-r_encrypted_unlocked,media/cd-rw_unmounted,media/cd-rw_encrypted_unlocked,media/dvd_unmounted,media/dvd_encrypted_unlocked,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/hdd_encrypted_unlocked,media/nfs_unmounted,media/removable_unmounted,media/removable_encrypted_unlocked,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted +X-TDE-ServiceTypes=media/bluray_unmounted,media/camera_unmounted,media/cdrom_unmounted,media/cd-r_unmounted,media/cd-rw_unmounted,media/dvd_unmounted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/nfs_unmounted,media/removable_unmounted,media/smb_unmounted,media/zip_unmounted,media/audiocd,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd Actions=MediaMount; X-TDE-Priority=TopLevel -X-TDE-MediaNotifierHide=true +X-TDE-MediaNotifierHide=false [Desktop Action MediaMount] -Name=Mount - Exec=tdeio_media_mounthelper -m %u +Icon=drive-harddisk-mounted +Name=Mount diff --git a/tdeioslave/media/services/media_realfolder.desktop b/tdeioslave/media/services/media_realfolder.desktop new file mode 100644 index 000000000..a89066c53 --- /dev/null +++ b/tdeioslave/media/services/media_realfolder.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +X-TDE-ServiceTypes=media/bluray_mounted,media/bluray_unmounted,media/camera_mounted,media/camera_unmounted,media/cdrom_mounted,media/cdrom_unmounted,media/cd-r_mounted,media/cd-r_unmounted,media/cd-rw_mounted,media/cd-rw_unmounted,media/dvd_mounted,media/dvd_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/floppy_mounted,media/floppy_unmounted,media/hdd_mounted,media/hdd_unmounted,media/nfs_mounted,media/nfs_unmounted,media/removable_mounted,media/removable_unmounted,media/smb_mounted,media/smb_unmounted,media/zip_mounted,media/zip_unmounted,media/audiocd,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd +Actions=MediaRealFolder +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=false + +[Desktop Action MediaRealFolder] +Exec=tdeio_media_mounthelper -f %u +Icon=folder_red +Name=Open Medium System Folder diff --git a/tdeioslave/media/services/media_safelyremove.desktop b/tdeioslave/media/services/media_safelyremove.desktop index 5abfdcd85..cf7191c8b 100644 --- a/tdeioslave/media/services/media_safelyremove.desktop +++ b/tdeioslave/media/services/media_safelyremove.desktop @@ -1,10 +1,10 @@ [Desktop Entry] -X-TDE-ServiceTypes=media/removable_mounted,media/removable_unmounted,media/removable_encrypted_unlocked,media/camera_mounted,media/camera_unmounted +X-TDE-ServiceTypes=media/bluray_mounted,media/bluray_unmounted,media/bluray_encrypted_locked,media/bluray_encrypted_unlocked,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_encrypted_locked,media/cdrom_encrypted_unlocked,media/cd-r_mounted,media/cd-r_unmounted,media/cd-r_encrypted_locked,media/cd-r_encrypted_unlocked,media/cd-rw_mounted,media/cd-rw_unmounted,media/cd-rw_encrypted_locked,media/cd-rw_encrypted_unlocked,media/dvd_mounted,media/dvd_unmounted,media/dvd_encrypted_locked,media/dvd_encrypted_unlocked,media/audiocd,media/blankbluray,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd,media/camera_mounted,media/camera_unmounted,media/removable_mounted,media/removable_unmounted,media/removable_encrypted_locked,media/removable_encrypted_unlocked Actions=MediaSafelyRemove; X-TDE-Priority=TopLevel X-TDE-MediaNotifierHide=true [Desktop Action MediaSafelyRemove] -Name=Safely Remove - Exec=tdeio_media_mounthelper -s %u +Icon=player_safe_removal +Name=Safely Remove diff --git a/tdeioslave/media/services/media_unlock.desktop b/tdeioslave/media/services/media_unlock.desktop new file mode 100644 index 000000000..8d15cd46e --- /dev/null +++ b/tdeioslave/media/services/media_unlock.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +X-TDE-ServiceTypes=media/bluray_encrypted_locked,media/cdrom_encrypted_locked,media/cd-r_encrypted_locked,media/cd-rw_encrypted_locked,media/dvd_encrypted_locked,media/hdd_encrypted_locked,media/removable_encrypted_locked +Actions=MediaUnlock; +X-TDE-Priority=TopLevel +X-TDE-MediaNotifierHide=false + +[Desktop Action MediaUnlock] +Exec=tdeio_media_mounthelper -k %u +Icon=decrypted +Name=Unlock diff --git a/tdeioslave/media/services/media_unmount.desktop b/tdeioslave/media/services/media_unmount.desktop index 32bd58406..38370dd25 100644 --- a/tdeioslave/media/services/media_unmount.desktop +++ b/tdeioslave/media/services/media_unmount.desktop @@ -1,10 +1,10 @@ [Desktop Entry] -X-TDE-ServiceTypes=media/removable_mounted,media/bluray_mounted,media/cdrom_mounted,media/cd-r_mounted,media/cd-rw_mounted,media/dvd_mounted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd,media/camera_mounted +X-TDE-ServiceTypes=media/bluray_mounted,media/camera_mounted,media/cdrom_mounted,media/cd-r_mounted,media/cd-rw_mounted,media/dvd_mounted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/nfs_mounted,media/removable_mounted,media/smb_mounted,media/zip_mounted,media/audiocd,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd Actions=MediaUnmount; X-TDE-Priority=TopLevel X-TDE-MediaNotifierHide=true [Desktop Action MediaUnmount] -Name=Unmount - Exec=tdeio_media_mounthelper -u %u +Icon=drive-harddisk-unmounted +Name=Unmount diff --git a/tdeioslave/media/tdecmodule/main.cpp b/tdeioslave/media/tdecmodule/main.cpp index e2d367e7d..dabac39aa 100644 --- a/tdeioslave/media/tdecmodule/main.cpp +++ b/tdeioslave/media/tdecmodule/main.cpp @@ -49,13 +49,13 @@ MediaModule::MediaModule( TQWidget *parent, const char *name, const TQStringList m_notifierModule = new NotifierModule( this, "notifier" ); tab->addTab( m_notifierModule, i18n( "&Notifications" ) ); - connect( m_notifierModule, TQT_SIGNAL( changed( bool ) ), - this, TQT_SLOT( moduleChanged( bool ) ) ); + connect( m_notifierModule, TQ_SIGNAL( changed( bool ) ), + this, TQ_SLOT( moduleChanged( bool ) ) ); m_managerModule = new ManagerModule( this, "manager" ); tab->addTab( m_managerModule, i18n( "&Advanced" ) ); - connect( m_managerModule, TQT_SIGNAL( changed( bool ) ), - this, TQT_SLOT( moduleChanged( bool ) ) ); + connect( m_managerModule, TQ_SIGNAL( changed( bool ) ), + this, TQ_SLOT( moduleChanged( bool ) ) ); diff --git a/tdeioslave/media/tdecmodule/main.h b/tdeioslave/media/tdecmodule/main.h index 5052d58eb..29d9eb21f 100644 --- a/tdeioslave/media/tdecmodule/main.h +++ b/tdeioslave/media/tdecmodule/main.h @@ -24,7 +24,7 @@ class MediaModule : public TDECModule { - Q_OBJECT + TQ_OBJECT public: MediaModule( TQWidget *parent, const char *name, const TQStringList& ); diff --git a/tdeioslave/media/tdecmodule/managermodule.cpp b/tdeioslave/media/tdecmodule/managermodule.cpp index 6478ee2a8..03a5ea500 100644 --- a/tdeioslave/media/tdecmodule/managermodule.cpp +++ b/tdeioslave/media/tdecmodule/managermodule.cpp @@ -44,13 +44,6 @@ ManagerModule::ManagerModule( TQWidget* parent, const char* name ) addConfig( MediaManagerSettings::self(), view ); -#ifndef COMPILE_HALBACKEND - TQString hal_text = view->kcfg_HalBackendEnabled->text(); - hal_text += " ("+i18n("No support for HAL on this system")+")"; - view->kcfg_HalBackendEnabled->setText( hal_text ); -#endif - view->kcfg_HalBackendEnabled->setEnabled( false ); - #ifndef COMPILE_LINUXCDPOLLING TQString poll_text = view->kcfg_CdPollingEnabled->text(); poll_text += " ("+i18n("No support for CD polling on this system")+")"; @@ -58,16 +51,16 @@ ManagerModule::ManagerModule( TQWidget* parent, const char* name ) #endif view->kcfg_CdPollingEnabled->setEnabled( false ); - connect( view->option_automount, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_ro, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_quiet, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_flush, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_uid, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_utf8, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_sync, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_atime, SIGNAL( stateChanged(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_shortname, SIGNAL( activated(int) ), this, SLOT( emitChanged() ) ); - connect( view->option_journaling, SIGNAL( activated(int) ), this, SLOT( emitChanged() ) ); + connect( view->option_automount, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_ro, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_quiet, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_flush, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_uid, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_utf8, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_sync, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_atime, TQ_SIGNAL( stateChanged(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_shortname, TQ_SIGNAL( activated(int) ), this, TQ_SLOT( emitChanged() ) ); + connect( view->option_journaling, TQ_SIGNAL( activated(int) ), this, TQ_SLOT( emitChanged() ) ); load(); } @@ -98,7 +91,7 @@ void ManagerModule::load() else view->option_atime->setNoChange(); - QString value; + TQString value; value = config.readEntry("shortname", "lower").lower(); for (int i = 0; i < view->option_shortname->count(); i++) @@ -140,13 +133,12 @@ void ManagerModule::save() rememberSettings(); - //Well... reloadBackends is buggy with HAL, it seems to be linked - //to a bug in the unmaintained Qt3 DBUS binding ;-/ - //DCOPRef mediamanager( "kded", "mediamanager" ); - //DCOPReply reply = mediamanager.call( "reloadBackends" ); - - // So we use this hack instead... DCOPRef kded( "kded", "kded" ); + // DCOPReply reply = mediamanager.call( "reloadBackends" ); + // Well... reloadBackends had issues with HAL, it seems it was linked + // to a bug in the unmaintained Qt3 DBUS binding, but it is not quite clear. + // It may be ok now that HAL is no longer supported but needs to be tested. + // So we use this hack instead... kded.call( "unloadModule", "mediamanager" ); kded.call( "loadModule", "mediamanager" ); diff --git a/tdeioslave/media/tdecmodule/managermodule.h b/tdeioslave/media/tdecmodule/managermodule.h index a0a384675..ae79e8d78 100644 --- a/tdeioslave/media/tdecmodule/managermodule.h +++ b/tdeioslave/media/tdecmodule/managermodule.h @@ -27,7 +27,7 @@ class ManagerModuleView; class ManagerModule : public TDECModule { - Q_OBJECT + TQ_OBJECT public: ManagerModule( TQWidget* parent = 0, const char* name = 0); diff --git a/tdeioslave/media/tdecmodule/managermoduleview.ui b/tdeioslave/media/tdecmodule/managermoduleview.ui index febef70f7..748cd825c 100644 --- a/tdeioslave/media/tdecmodule/managermoduleview.ui +++ b/tdeioslave/media/tdecmodule/managermoduleview.ui @@ -21,46 +21,46 @@ </property> <widget class="TQCheckBox"> <property name="name"> - <cstring>kcfg_HalBackendEnabled</cstring> + <cstring>kcfg_CdPollingEnabled</cstring> </property> <property name="text"> - <string>Enable HAL backend</string> + <string>Enable CD polling</string> </property> <property name="whatsThis" stdset="0"> - <string>Select this if you want to enable the Hardware Abstraction Layer (http://hal.freedesktop.org/wiki/Software/hal) support.</string> + <string>Select this to enable the CD polling.</string> </property> </widget> <widget class="TQCheckBox"> <property name="name"> - <cstring>kcfg_CdPollingEnabled</cstring> + <cstring>kcfg_AutostartEnabled</cstring> </property> <property name="text"> - <string>Enable CD polling</string> + <string>Enable medium application autostart after mount</string> </property> <property name="whatsThis" stdset="0"> - <string>Select this to enable the CD polling.</string> + <string>Select this if you want to enable application autostart after mounting a device.</string> </property> </widget> <widget class="TQCheckBox"> <property name="name"> - <cstring>kcfg_AutostartEnabled</cstring> + <cstring>kcfg_NotificationPopupsEnabled</cstring> </property> <property name="text"> - <string>Enable medium application autostart after mount</string> + <string>Enable notification dialog popups</string> </property> <property name="whatsThis" stdset="0"> - <string>Select this if you want to enable application autostart after mounting a device.</string> + <string>Deselect this if you do not want action request dialog popups to be generated when devices are plugged in.</string> </property> </widget> <widget class="TQCheckBox"> <property name="name"> - <cstring>kcfg_NotificationPopupsEnabled</cstring> + <cstring>kcfg_DeviceMonitorPopupsEnabled</cstring> </property> <property name="text"> - <string>Enable notification popups</string> + <string>Enable device monitor notification popups</string> </property> <property name="whatsThis" stdset="0"> - <string>Deselect this if you do not want action request popups to be generated when devices are plugged in.</string> + <string>Deselect this if you do not want device monitoring popups to be generated when devices are added, modified or removed.</string> </property> </widget> <widget class="TQGroupBox"> @@ -337,19 +337,11 @@ Display the short name as is; store a long name when the short name is not all u </spacer> </vbox> </widget> -<connections> - <connection> - <sender>kcfg_HalBackendEnabled</sender> - <signal>toggled(bool)</signal> - <receiver>groupbox_mount</receiver> - <slot>setEnabled(bool)</slot> - </connection> -</connections> <tabstops> - <tabstop>kcfg_HalBackendEnabled</tabstop> <tabstop>kcfg_CdPollingEnabled</tabstop> <tabstop>kcfg_AutostartEnabled</tabstop> <tabstop>kcfg_NotificationPopupsEnabled</tabstop> + <tabstop>kcfg_DeviceMonitorPopupsEnabled</tabstop> <tabstop>option_automount</tabstop> <tabstop>option_ro</tabstop> <tabstop>option_quiet</tabstop> diff --git a/tdeioslave/media/tdecmodule/notifiermodule.cpp b/tdeioslave/media/tdecmodule/notifiermodule.cpp index 4364d93ad..2d2d53481 100644 --- a/tdeioslave/media/tdecmodule/notifiermodule.cpp +++ b/tdeioslave/media/tdecmodule/notifiermodule.cpp @@ -57,18 +57,18 @@ NotifierModule::NotifierModule(TQWidget *parent, const char *name) updateListBox(); - connect( m_view->mimetypesCombo, TQT_SIGNAL( activated(int) ), - this, TQT_SLOT( slotMimeTypeChanged(int) ) ); - connect( m_view->actionsList, TQT_SIGNAL( selectionChanged(TQListBoxItem*) ), - this, TQT_SLOT( slotActionSelected(TQListBoxItem*) ) ); - connect( m_view->addButton, TQT_SIGNAL( clicked() ), - this, TQT_SLOT( slotAdd() ) ); - connect( m_view->editButton, TQT_SIGNAL( clicked() ), - this, TQT_SLOT( slotEdit() ) ); - connect( m_view->deleteButton, TQT_SIGNAL( clicked() ), - this, TQT_SLOT( slotDelete() ) ); - connect( m_view->toggleAutoButton, TQT_SIGNAL( clicked() ), - this, TQT_SLOT( slotToggleAuto() ) ); + connect( m_view->mimetypesCombo, TQ_SIGNAL( activated(int) ), + this, TQ_SLOT( slotMimeTypeChanged(int) ) ); + connect( m_view->actionsList, TQ_SIGNAL( selectionChanged(TQListBoxItem*) ), + this, TQ_SLOT( slotActionSelected(TQListBoxItem*) ) ); + connect( m_view->addButton, TQ_SIGNAL( clicked() ), + this, TQ_SLOT( slotAdd() ) ); + connect( m_view->editButton, TQ_SIGNAL( clicked() ), + this, TQ_SLOT( slotEdit() ) ); + connect( m_view->deleteButton, TQ_SIGNAL( clicked() ), + this, TQ_SLOT( slotDelete() ) ); + connect( m_view->toggleAutoButton, TQ_SIGNAL( clicked() ), + this, TQ_SLOT( slotToggleAuto() ) ); } NotifierModule::~NotifierModule() diff --git a/tdeioslave/media/tdecmodule/notifiermodule.h b/tdeioslave/media/tdecmodule/notifiermodule.h index d5d97a96d..2192c30a9 100644 --- a/tdeioslave/media/tdecmodule/notifiermodule.h +++ b/tdeioslave/media/tdecmodule/notifiermodule.h @@ -28,7 +28,7 @@ class NotifierModule : public TDECModule { - Q_OBJECT + TQ_OBJECT public: NotifierModule( TQWidget* parent = 0, const char* name = 0); diff --git a/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp b/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp index 4147e437c..bcf533b9d 100644 --- a/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp +++ b/tdeioslave/media/tdecmodule/serviceconfigdialog.cpp @@ -78,10 +78,10 @@ ServiceConfigDialog::ServiceConfigDialog(NotifierServiceAction *action, setMainWidget(m_view); setCaption( m_action->label() ); - connect( m_view->iconButton, TQT_SIGNAL( iconChanged(TQString) ), - this, TQT_SLOT( slotIconChanged() ) ); - connect( m_view->commandButton, TQT_SIGNAL( clicked() ), - this, TQT_SLOT( slotCommand() ) ); + connect( m_view->iconButton, TQ_SIGNAL( iconChanged(TQString) ), + this, TQ_SLOT( slotIconChanged() ) ); + connect( m_view->commandButton, TQ_SIGNAL( clicked() ), + this, TQ_SLOT( slotCommand() ) ); } bool operator==( KDEDesktopMimeType::Service s1, KDEDesktopMimeType::Service s2 ) diff --git a/tdeioslave/media/tdecmodule/serviceconfigdialog.h b/tdeioslave/media/tdecmodule/serviceconfigdialog.h index 24e907205..2f35bfb54 100644 --- a/tdeioslave/media/tdecmodule/serviceconfigdialog.h +++ b/tdeioslave/media/tdecmodule/serviceconfigdialog.h @@ -27,7 +27,7 @@ class ServiceConfigDialog : public KDialogBase { - Q_OBJECT + TQ_OBJECT public: ServiceConfigDialog(NotifierServiceAction *action, diff --git a/tdeioslave/media/tdefile-plugin/tdefile_media.desktop b/tdeioslave/media/tdefile-plugin/tdefile_media.desktop index bfb7a6762..2b9b7c68e 100644 --- a/tdeioslave/media/tdefile-plugin/tdefile_media.desktop +++ b/tdeioslave/media/tdefile-plugin/tdefile_media.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Type=Service X-TDE-Library=tdefile_media -X-TDE-ServiceTypes=KFilePlugin,media/audiocd,media/blankcd,media/blankbluray,media/blankdvd,media/hdd_mounted,media/hdd_unmounted,media/hdd_encrypted_unlocked,media/bluray_mounted,media/bluray_unmounted,media/bluray_encrypted_unlocked,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_encrypted_unlocked,media/cd-r_mounted,media/cd-r_unmounted,media/cd-r_encrypted_unlocked,media/cd-rw_mounted,media/cd-rw_unmounted,media/cd-rw_encrypted_unlocked,media/dvd_mounted,media/dvd_unmounted,media/dvd_encrypted_unlocked,media/removable_mounted,media/removable_unmounted,media/removable_encrypted_unlocked,media/nfs_mounted,media/nfs_unmounted,media/smb_mounted,media/smb_unmounted,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd,media/floppy_mounted,media/floppy_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/zip_mounted,media/zip_unmounted,media/gphoto2camera,media/camera_mounted,media/camera_unmounted +X-TDE-ServiceTypes=KFilePlugin,media/audiocd,media/blankcd,media/blankbluray,media/blankdvd,media/hdd_mounted,media/hdd_unmounted,media/hdd_encrypted_unlocked,media/hdd_encrypted_locked,media/bluray_mounted,media/bluray_unmounted,media/bluray_encrypted_unlocked,media/bluray_encrypted_locked,media/cdrom_mounted,media/cdrom_unmounted,media/cdrom_encrypted_unlocked,media/cdrom_encrypted_locked,media/cd-r_mounted,media/cd-r_unmounted,media/cd-r_encrypted_unlocked,media/cd-r_encrypted_locked,media/cd-rw_mounted,media/cd-rw_unmounted,media/cd-rw_encrypted_unlocked,media/cd-rw_encrypted_locked,media/dvd_mounted,media/dvd_unmounted,media/dvd_encrypted_unlocked,media/dvd_encrypted_locked,media/removable_mounted,media/removable_unmounted,media/removable_encrypted_unlocked,media/removable_encrypted_locked,media/nfs_mounted,media/nfs_unmounted,media/smb_mounted,media/smb_unmounted,media/blurayvideo,media/dvdvideo,media/svcd,media/vcd,media/floppy_mounted,media/floppy_unmounted,media/floppy5_mounted,media/floppy5_unmounted,media/zip_mounted,media/zip_unmounted,media/gphoto2camera,media/camera_mounted,media/camera_unmounted Name=Medium Information diff --git a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp index b7e4a437d..190bec197 100644 --- a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp +++ b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp @@ -55,24 +55,31 @@ KFileMediaPlugin::KFileMediaPlugin(TQObject *parent, const char *name, addMimeType( "media/bluray_mounted" ); addMimeType( "media/bluray_unmounted" ); addMimeType( "media/bluray_encrypted_unlocked" ); + addMimeType( "media/bluray_encrypted_locked" ); addMimeType( "media/cdrom_mounted" ); addMimeType( "media/cdrom_unmounted" ); addMimeType( "media/cdrom_encrypted_unlocked" ); + addMimeType( "media/cdrom_encrypted_locked" ); addMimeType( "media/cd-r_mounted" ); addMimeType( "media/cd-r_unmounted" ); addMimeType( "media/cd-r_encrypted_unlocked" ); + addMimeType( "media/cd-r_encrypted_locked" ); addMimeType( "media/cd-rw_mounted" ); addMimeType( "media/cd-rw_unmounted" ); addMimeType( "media/cd-rw_encrypted_unlocked" ); + addMimeType( "media/cd-rw_encrypted_locked" ); addMimeType( "media/dvd_mounted" ); addMimeType( "media/dvd_unmounted" ); addMimeType( "media/dvd_encrypted_unlocked" ); + addMimeType( "media/dvd_encrypted_locked" ); addMimeType( "media/hdd_mounted" ); addMimeType( "media/hdd_unmounted" ); addMimeType( "media/hdd_encrypted_unlocked" ); + addMimeType( "media/hdd_encrypted_locked" ); addMimeType( "media/removable_mounted" ); addMimeType( "media/removable_unmounted" ); addMimeType( "media/removable_encrypted_unlocked" ); + addMimeType( "media/removable_encrypted_locked" ); addMimeType( "media/nfs_mounted" ); addMimeType( "media/nfs_unmounted" ); addMimeType( "media/smb_mounted" ); @@ -151,12 +158,12 @@ bool KFileMediaPlugin::readInfo(KFileMetaInfo &info, uint /*what*/) TQPixmap bar(150, 20); TQPainter p(&bar); - p.fillRect(0, 0, length, 20, Qt::red); - p.fillRect(length, 0, 150-length, 20, Qt::green); + p.fillRect(0, 0, length, 20, TQt::red); + p.fillRect(length, 0, 150-length, 20, TQt::green); TQColorGroup cg = TQApplication::palette().active(); - TQApplication::style().tqdrawPrimitive(TQStyle::PE_Panel, &p, + TQApplication::style().drawPrimitive(TQStyle::PE_Panel, &p, TQRect(0, 0, 150, 20), cg, TQStyle::Style_Sunken); diff --git a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h index dcc2591be..0f9dc0038 100644 --- a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h +++ b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.h @@ -28,7 +28,7 @@ class KFileMediaPlugin : public KFilePlugin { -Q_OBJECT +TQ_OBJECT public: KFileMediaPlugin(TQObject *parent, const char *name, const TQStringList &args); diff --git a/tdeioslave/media/tdeio_media.cpp b/tdeioslave/media/tdeio_media.cpp index 9124568c1..c68bc25d5 100644 --- a/tdeioslave/media/tdeio_media.cpp +++ b/tdeioslave/media/tdeio_media.cpp @@ -62,8 +62,8 @@ MediaProtocol::MediaProtocol(const TQCString &protocol, const TQCString &pool, const TQCString &app) : ForwardingSlaveBase(protocol, pool, app) { - connect( &m_impl, TQT_SIGNAL( warning( const TQString & ) ), - this, TQT_SLOT( slotWarning( const TQString & ) ) ); + connect( &m_impl, TQ_SIGNAL( warning( const TQString & ) ), + this, TQ_SLOT( slotWarning( const TQString & ) ) ); } MediaProtocol::~MediaProtocol() diff --git a/tdeioslave/media/tdeio_media.h b/tdeioslave/media/tdeio_media.h index 7acc44df0..473a623b1 100644 --- a/tdeioslave/media/tdeio_media.h +++ b/tdeioslave/media/tdeio_media.h @@ -26,7 +26,7 @@ class MediaProtocol : public TDEIO::ForwardingSlaveBase { -Q_OBJECT +TQ_OBJECT public: MediaProtocol(const TQCString &protocol, const TQCString &pool, const TQCString &app); diff --git a/tdeioslave/nfs/tdeio_nfs.cpp b/tdeioslave/nfs/tdeio_nfs.cpp index 8a7fd94b8..e2908f815 100644 --- a/tdeioslave/nfs/tdeio_nfs.cpp +++ b/tdeioslave/nfs/tdeio_nfs.cpp @@ -425,7 +425,7 @@ void NFSProtocol::openConnection() hostName=nameBuffer; // I have the same problem here as Stefan Westerfeld, that's why I use // the getdomainname() from fakes.cpp (renamed to x_getdomainname()), this one works - // taken from tdelibs/arts/mcopy/mcoputils.cc + // taken from tdelibs/arts/mcopy/mcoputils.cpp nameBuffer[0] = '\0'; if (x_getdomainname(nameBuffer, 1024)==0) { @@ -777,7 +777,7 @@ void NFSProtocol::stat( const KURL & url) void NFSProtocol::completeAbsoluteLinkUDSEntry(UDSEntry& entry, const TQCString& path) { - //taken from file.cc + //taken from file.cpp struct stat buff; if ( ::stat( path.data(), &buff ) == -1 ) return; diff --git a/tdeioslave/pop3/CMakeLists.txt b/tdeioslave/pop3/CMakeLists.txt index e488d5e99..725abcabf 100644 --- a/tdeioslave/pop3/CMakeLists.txt +++ b/tdeioslave/pop3/CMakeLists.txt @@ -35,7 +35,7 @@ tde_create_translated_desktop( set( target tdeio_pop3 ) tde_add_kpart( ${target} AUTOMOC - SOURCES pop3.cc + SOURCES pop3.cpp LINK tdeio-shared ${SASL_LIBRARIES} DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/pop3/Makefile.am b/tdeioslave/pop3/Makefile.am index 130fb34d8..1dc92b73b 100644 --- a/tdeioslave/pop3/Makefile.am +++ b/tdeioslave/pop3/Makefile.am @@ -4,7 +4,7 @@ INCLUDES= -I$(srcdir)/../.. -I$(srcdir)/.. $(SSL_INCLUDES) $(all_includes) kde_module_LTLIBRARIES = tdeio_pop3.la -tdeio_pop3_la_SOURCES = pop3.cc +tdeio_pop3_la_SOURCES = pop3.cpp tdeio_pop3_la_LIBADD = $(LIB_TDEIO) $(SASL2_LIBS) tdeio_pop3_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) @@ -14,4 +14,4 @@ kdelnk_DATA = pop3.protocol pop3s.protocol kdelnkdir = $(kde_servicesdir) messages: - $(XGETTEXT) *.cc -o $(podir)/tdeio_pop3.pot + $(XGETTEXT) *.cpp -o $(podir)/tdeio_pop3.pot diff --git a/tdeioslave/pop3/pop3.cc b/tdeioslave/pop3/pop3.cpp index f45f06d60..f45f06d60 100644 --- a/tdeioslave/pop3/pop3.cc +++ b/tdeioslave/pop3/pop3.cpp diff --git a/tdeioslave/remote/Makefile.am b/tdeioslave/remote/Makefile.am index 9505065f3..988016d3c 100644 --- a/tdeioslave/remote/Makefile.am +++ b/tdeioslave/remote/Makefile.am @@ -28,5 +28,5 @@ check: testremote ./testremote messages: - $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_remote.pot + $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_remote.pot diff --git a/tdeioslave/settings/CMakeLists.txt b/tdeioslave/settings/CMakeLists.txt index 04fc4e69f..0b05ff0c1 100644 --- a/tdeioslave/settings/CMakeLists.txt +++ b/tdeioslave/settings/CMakeLists.txt @@ -35,7 +35,7 @@ tde_create_translated_desktop( set( target tdeio_settings ) tde_add_kpart( ${target} AUTOMOC - SOURCES tdeio_settings.cc + SOURCES tdeio_settings.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/settings/Makefile.am b/tdeioslave/settings/Makefile.am index b470a7782..5b804af90 100644 --- a/tdeioslave/settings/Makefile.am +++ b/tdeioslave/settings/Makefile.am @@ -4,7 +4,7 @@ INCLUDES= $(all_includes) kde_module_LTLIBRARIES = tdeio_settings.la -tdeio_settings_la_SOURCES = tdeio_settings.cc +tdeio_settings_la_SOURCES = tdeio_settings.cpp tdeio_settings_la_LIBADD = $(LIB_TDESYCOCA) tdeio_settings_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) @@ -17,5 +17,5 @@ kdelnkdir = $(kde_servicesdir) SUBDIRS=. messages: - $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_settings.pot + $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_settings.pot diff --git a/tdeioslave/settings/tdeio_settings.cc b/tdeioslave/settings/tdeio_settings.cpp index db797fab5..5d1e67a0e 100644 --- a/tdeioslave/settings/tdeio_settings.cc +++ b/tdeioslave/settings/tdeio_settings.cpp @@ -294,5 +294,3 @@ void SettingsProtocol::listDir(const KURL& url) listEntry(entry, true); finished(); } - -// vim: ts=4 sw=4 et diff --git a/tdeioslave/sftp/AUTHORS b/tdeioslave/sftp/AUTHORS deleted file mode 100644 index c763d00bc..000000000 --- a/tdeioslave/sftp/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Dawit Alemayehu <adawit@kde.org> -Lucas Fisher <ljfisher@iastate.edu> - diff --git a/tdeioslave/sftp/CHANGELOG b/tdeioslave/sftp/CHANGELOG deleted file mode 100644 index c34cd9dec..000000000 --- a/tdeioslave/sftp/CHANGELOG +++ /dev/null @@ -1,59 +0,0 @@ -- add dialog to ask for username -- rename() causes SSH to die -- How to handle overwrite? -- After the user cancels with the stop button, we get ERR_CANNOT_LAUNCH_PROCESS - errors, until we kill the ioslave. Same thing after trying the wrong passwd - too many times. - This is happening because TDEProcess thinks that the ssh process is still running - even though it exited. -- How to handle password and caching? - - Write our own askpass program using kde - - set env SSH_ASKPASS_PROGRAM before launching - -how to do this? TDEProcess doesn't give us access to env variables. - - Our askpass program can probably talk to the tdesu daemon to implement caching. -- chmod() succeeds, but konqueror always puts permissions to 0 afterwards. The properties - dialog is right though. - Nevermind - ftp ioslave does this too! Maybe a bug with konqueror. -- stat does not give us group and owner names, only numbers. We could cache the uid/name and - gid/name so we can give names when doing a stat also. - -7-13-2001 - ReadLink stopped working. sftp server always retuns a file not found error - - Need to implement 64 bit file lengths-->write DataStream << for u_int64 - Still need to offer 32 bit size since this is what kde wants. ljf - - rename() isn't exactly causing ioslave to die. The stat of the file we are - going to rename is killing the slave. The slave dies in the statEntry() call. - I don't know what I am putting in the UDS entry that is causing this. ljf -7-14-2001 - got put, mimetype working ljf - - fixed readlink problem - I was sending the wrong path. doh! ljf -7-17-2001 - If the user changes the host, the slave doesn't change host! setHost() is not - called, nor is another ioslave spawned. I have not investigated the problem - yet. ljf -7-21-2001 - got slave working with kde 2.2 cvs -7-22-2001 - probable solution to getting password prompt -- open with controlling - but don't connect stdin/out to terminal. duh! -8-9-2001 - Doh! I haven't kept very good logs. Look at the cvs logs for better info. - - At this point tdeio_sftp is using KSshProcess which I wrote in order to make - a standard interface to the various version of ssh out there. So far it is - working fairly well. We also now report host key changes to the user and - allow them to choose whether or not to continue. This is a big improvement. - - Todo: support use of keys and ssh agent - put()'s resume functionality needs some work -1-26-2002 - Rewrote put() following the ftp::put() so it should behave the same way - - increase the size of the data packet we ask for in ::get up to 60k. - Through-put increases nicely. - - Call closeConnection() from construction. Keeps from having unused ssh - processes laying around after failed operations. -2-19-2002 - get() now emits mimetype, fixes problem with konqi not downloading file for - viewing in kpart. - - get port number using getservbyname instead of hard coding it. -2-27-2002 - testing before committing back to cvs, test with openssh 3, ssh 3 -6-?-2002 - rewrote openConnection() to using new KSshProcess connect proceedures -7-20-2002 - Don't put up a message box when auth fails because of now or changed key, - the call to error() will put up the dialog. - - Connect fails and no more password are prompted for when we get - ERR_AUTH_FAILED from KSshProcess. -9-15-2002 - stuff -9-29-2002 - the last i18n string updates, fixed problem with uploading files to - openssh server. -5-8-2003 - check whether operation types are supported by the negotiated sftp - protocol version diff --git a/tdeioslave/sftp/CMakeLists.txt b/tdeioslave/sftp/CMakeLists.txt index 62fe0fce3..8074ea76e 100644 --- a/tdeioslave/sftp/CMakeLists.txt +++ b/tdeioslave/sftp/CMakeLists.txt @@ -1,13 +1,10 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# +########################################### +# # +# Improvements and feedback are welcome # +# # +# This file is released under GPL >= 2 # +# # +########################################### include_directories( ${CMAKE_CURRENT_BINARY_DIR} @@ -21,7 +18,7 @@ link_directories( ) -##### other data ################################ +##### other data ######################### tde_create_translated_desktop( SOURCE sftp.protocol @@ -30,12 +27,12 @@ tde_create_translated_desktop( ) -##### tdeio_sftp (module) ######################### +##### tdeio_sftp (module) ################ set( target tdeio_sftp ) tde_add_kpart( ${target} AUTOMOC - SOURCES process.cpp atomicio.cpp tdeio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp - LINK tdeio-shared tdesu-shared + SOURCES tdeio_sftp.cpp + LINK tdeio-shared ssh DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/sftp/DEBUGGING b/tdeioslave/sftp/DEBUGGING deleted file mode 100644 index 8e15c91d4..000000000 --- a/tdeioslave/sftp/DEBUGGING +++ /dev/null @@ -1,12 +0,0 @@ -DEBUGGING - -The best way to debug this slave is to send debug info to a -file using 'tdedebugDialog --fullmode'. Then you can 'tail -f' the file to -see debug messages in real-time. - -I also suggest getting the openssh source and recompiling sftp-server to -send messages to the auth log. This can be done in sftp-server.c be defining -DEBUG_SFTP_SERVER. - -You can do the same with the ssh client by finding the two calls to log_init() -in ssh.c and changing the last argument from 1 to 0 and recompiling. diff --git a/tdeioslave/sftp/Makefile.am b/tdeioslave/sftp/Makefile.am deleted file mode 100644 index 512f5f7dd..000000000 --- a/tdeioslave/sftp/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -## Makefile.am of tdebase/tdeioslave/sftp - -INCLUDES = $(all_includes) -AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_TQT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor -METASOURCES = AUTO - -####### Files - -check_PROGRAMS = ksshprocesstest - -ksshprocesstest_SOURCES = ksshprocesstest.cpp -ksshprocesstest_LDADD = $(LIB_TDESYCOCA) ksshprocess.lo process.lo atomicio.lo - -kde_module_LTLIBRARIES = tdeio_sftp.la - -tdeio_sftp_la_SOURCES = process.cpp atomicio.cpp tdeio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp -tdeio_sftp_la_LIBADD = $(LIB_TDEIO) -tdeio_sftp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = atomicio.h tdeio_sftp.h ksshprocess.h process.h sftpfileattr.h sftp.h - -kdelnk_DATA = sftp.protocol -kdelnkdir = $(kde_servicesdir) - -messages: - $(XGETTEXT) *.cpp -o $(podir)/tdeio_sftp.pot diff --git a/tdeioslave/sftp/TODO b/tdeioslave/sftp/TODO deleted file mode 100644 index 0f1411317..000000000 --- a/tdeioslave/sftp/TODO +++ /dev/null @@ -1,5 +0,0 @@ -TODO: -===== - -- Support for use of public keys, maybe ssh-agent, a key management app, etc. - diff --git a/tdeioslave/sftp/atomicio.cpp b/tdeioslave/sftp/atomicio.cpp deleted file mode 100644 index 057f20fe9..000000000 --- a/tdeioslave/sftp/atomicio.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//#include "includes.h" -//RCSID("$OpenBSD: atomicio.c,v 1.9 2001/03/02 18:54:30 deraadt Exp $"); - -//#include "xmalloc.h" -#include "atomicio.h" -#include <unistd.h> -#include <errno.h> -#include <kdebug.h> - -/* - * ensure all of data on socket comes through. f==read || f==write - */ - -ssize_t atomicio(int fd, char *_s, size_t n, bool read) -{ - char *s = _s; - ssize_t res; - ssize_t pos = 0; - - while (n > pos) { - if( read) - res = ::read(fd, s + pos, n - pos); - else - res = ::write(fd, s + pos, n - pos); - - switch (res) { - case -1: - kdDebug() << "atomicio(): errno=" << errno << endl; -#ifdef EWOULDBLOCK - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) -#else - if (errno == EINTR || errno == EAGAIN) -#endif - continue; - case 0: - return (res); - default: - pos += res; - } - } - return (pos); -} diff --git a/tdeioslave/sftp/atomicio.h b/tdeioslave/sftp/atomicio.h deleted file mode 100644 index 4468757d5..000000000 --- a/tdeioslave/sftp/atomicio.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef atomicio_h -#define atomicio_h - -/* $OpenBSD: atomicio.h,v 1.3 2001/03/02 18:54:30 deraadt Exp $ */ - -/* - * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <unistd.h> - -/* - * Ensure all of data on socket comes through. f==read || f==write - */ -ssize_t atomicio(int fd, char *_s, size_t n, bool read = true); - -#endif diff --git a/tdeioslave/sftp/ksshprocess.cpp b/tdeioslave/sftp/ksshprocess.cpp deleted file mode 100644 index 0f19126d2..000000000 --- a/tdeioslave/sftp/ksshprocess.cpp +++ /dev/null @@ -1,1114 +0,0 @@ -/*************************************************************************** - ksshprocess.cpp - description - ------------------- - begin : Tue Jul 31 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -/* - * See the KSshProcess header for examples on use. - * - * This class uses a hacked version of the PTYProcess - * class. This was needed because the tdelibs PTYProcess does not provide - * access to the pty file descriptor which we need, because ssh prints the - * password prompt to the pty and reads the password from the pty. I don't - * feel I know enough about ptys to confidently modify the orignial - * PTYProcess class. - * - * To start ssh we take the arguments the user gave us - * in the SshOptList and build the ssh command arguments based on the version - * of ssh we are using. This command and its arguments are passed to - * PTYProcess for execution. Once ssh is started we scan each line of input - * from stdin, stderr, and the pty for recognizable strings. The recognizable - * strings are taken from several string tables. Each table contains a string - * for each specific version of ssh we support and a string for a generic - * version of OpenSSH and commercial SSH incase we don't recognized the - * specific ssh version strings (as when a new SSH version is released after - * a release of KSshProcess). There are tables for ssh version strings, - * password prompts, new host key errors, different host key errors, - * messages than indicate a successful connect, authentication errors, etc. - * If we find user interaction is necessary, for instance to provide a - * password or passphrase, we return a err code to the user who can send - * a message to KSshProcess, using one of several methods, to correct - * the error. - * - * Determining when the ssh connection has successfully authenticationed has - * proved to be the most difficult challenge. OpenSSH does not print a message - * on successful authentication, thus the only way to know is to send data - * and wait for a return. The problem here is sometimes it can take a bit - * to establish the connection (for example, do to DNS lookups). This means - * the user may be sitting there waiting for a connection that failed. - * Instead, ssh is always started with the verbose flag. Then we look for - * a message that indicates auth succeeded. This is hazardous because - * debug messages are more likely to change between OpenSSH releases. - * Thus, we could become incompatible with new OpenSSH releases. - */ - -#include <config.h> - -#include "ksshprocess.h" - -#include <stdio.h> -#include <errno.h> - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#include <kstandarddirs.h> -#include <tdelocale.h> -#include <tqregexp.h> - -/* - * The following are tables of string and regexps we match - * against the output of ssh. An entry in each array - * corresponds the the version of ssh found in versionStrs[]. - * - * The version strings must be ordered in the array from most - * specific to least specific in cases where the beginning - * of several version strings are the similar. For example, - * consider the openssh version strings. The generic "OpenSSH" - * must be the last of the openssh version strings in the array - * so that is matched last. We use these generic version strings - * so we can do a best effor to support unknown ssh versions. - */ -TQRegExp KSshProcess::versionStrs[] = { - TQRegExp("OpenSSH_3\\.[6-9]|OpenSSH_[1-9]*[4-9]\\.[0-9]"), - TQRegExp("OpenSSH"), - TQRegExp("SSH Secure Shell") -}; - -const char * const KSshProcess::passwordPrompt[] = { - "password:", // OpenSSH - "password:", // OpenSSH - "password:" // SSH -}; - -const char * const KSshProcess::passphrasePrompt[] = { - "Enter passphrase for key", - "Enter passphrase for key", - "Passphrase for key" -}; - -const char * const KSshProcess::authSuccessMsg[] = { - "Authentication succeeded", - "ssh-userauth2 successful", - "Received SSH_CROSS_AUTHENTICATED packet" -}; - -const char* const KSshProcess::authFailedMsg[] = { - "Permission denied (", - "Permission denied (", - "Authentication failed." -}; - -const char* const KSshProcess::tryAgainMsg[] = { - "please try again", - "please try again", - "adjfhjsdhfdsjfsjdfhuefeufeuefe" -}; - -TQRegExp KSshProcess::hostKeyMissingMsg[] = { - TQRegExp("The authenticity of host|No (DSA|RSA) host key is known for"), - TQRegExp("The authenticity of host|No (DSA|RSA) host key is known for"), - TQRegExp("Host key not found from database") -}; - -const char* const KSshProcess::continuePrompt[] = { - "Are you sure you want to continue connecting (yes/no)?", - "Are you sure you want to continue connecting (yes/no)?", - "Are you sure you want to continue connecting (yes/no)?" -}; - -const char* const KSshProcess::hostKeyChangedMsg[] = { - "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!", - "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!", - "WARNING: HOST IDENTIFICATION HAS CHANGED!" -}; - -TQRegExp KSshProcess::keyFingerprintMsg[] = { - TQRegExp("..(:..){15}"), - TQRegExp("..(:..){15}"), - TQRegExp(".....(-.....){10}") -}; - -TQRegExp KSshProcess::knownHostsFileMsg[] = { - TQRegExp("Add correct host key in (.*) to get rid of this message."), - TQRegExp("Add correct host key in (.*) to get rid of this message."), - TQRegExp("Add correct host key to \"(.*)\"") -}; - - -// This prompt only applies to commerical ssh. -const char* const KSshProcess::changeHostKeyOnDiskPrompt[] = { - "as;jf;sajkfdslkfjas;dfjdsa;fj;dsajfdsajf", - "as;jf;sajkfdslkfjas;dfjdsa;fj;dsajfdsajf", - "Do you want to change the host key on disk (yes/no)?" -}; - -// We need this in addition the authFailedMsg because when -// OpenSSH gets a changed host key it will fail to connect -// depending on the StrictHostKeyChecking option. Depending -// how this option is set, it will print "Permission denied" -// and quit, or print "Host key verification failed." and -// quit. The later if StrictHostKeyChecking is "no". -// The former if StrictHostKeyChecking is -// "yes" or explicitly set to "ask". -TQRegExp KSshProcess::hostKeyVerifyFailedMsg[] = { - TQRegExp("Host key verification failed\\."), - TQRegExp("Host key verification failed\\."), - TQRegExp("Disconnected; key exchange or algorithm? negotiation failed \\(Key exchange failed\\.\\)\\.") -}; - -const char * const KSshProcess::connectionClosedMsg[] = { - "Connection closed by remote host", - "Connection closed by remote host", - "Connection closed by remote host" -}; - - -void KSshProcess::SIGCHLD_handler(int) { - while(waitpid(-1, NULL, WNOHANG) > 0); -} - -void KSshProcess::installSignalHandlers() { - struct sigaction act; - memset(&act,0,sizeof(act)); - act.sa_handler = SIGCHLD_handler; - act.sa_flags = 0 -#ifdef SA_NOCLDSTOP - | SA_NOCLDSTOP -#endif -#ifdef SA_RESTART - | SA_RESTART -#endif - ; - sigaction(SIGCHLD,&act,NULL); -} - -void KSshProcess::removeSignalHandlers() { - struct sigaction act; - memset(&act,0,sizeof(act)); - act.sa_handler = SIG_DFL; - sigaction(SIGCHLD,&act,NULL); -} - -KSshProcess::KSshProcess() - : mVersion(UNKNOWN_VER), mConnected(false), - mRunning(false), mConnectState(0) { - mSshPath = TDEStandardDirs::findExe(TQString::fromLatin1("ssh")); - kdDebug(KSSHPROC) << "KSshProcess::KSshProcess(): ssh path [" << - mSshPath << "]" << endl; - - installSignalHandlers(); -} - -KSshProcess::KSshProcess(TQString pathToSsh) - : mSshPath(pathToSsh), mVersion(UNKNOWN_VER), mConnected(false), - mRunning(false), mConnectState(0) { - installSignalHandlers(); -} - -KSshProcess::~KSshProcess(){ - disconnect(); - removeSignalHandlers(); - while(waitpid(-1, NULL, WNOHANG) > 0); -} - -bool KSshProcess::setSshPath(TQString pathToSsh) { - mSshPath = pathToSsh; - version(); - if( mVersion == UNKNOWN_VER ) - return false; - - return true; -} - -KSshProcess::SshVersion KSshProcess::version() { - TQString cmd; - cmd = mSshPath+" -V 2>&1"; - - // Get version string from ssh client. - FILE *p; - if( (p = popen(cmd.latin1(), "r")) == NULL ) { - kdDebug(KSSHPROC) << "KSshProcess::version(): " - "failed to start ssh: " << strerror(errno) << endl; - return UNKNOWN_VER; - } - - // Determine of the version from the version string. - size_t len; - char buf[128]; - if( (len = fread(buf, sizeof(char), sizeof(buf)-1, p)) == 0 ) { - kdDebug(KSSHPROC) << "KSshProcess::version(): " - "Read of ssh version string failed " << - strerror(ferror(p)) << endl; - return UNKNOWN_VER; - } - if( pclose(p) == -1 ) { - kdError(KSSHPROC) << "KSshProcess::version(): pclose failed." << endl; - } - buf[len] = '\0'; - TQString ver; - ver = buf; - kdDebug(KSSHPROC) << "KSshProcess::version(): " - "got version string [" << ver << "]" << endl; - - mVersion = UNKNOWN_VER; - for(int i = 0; i < SSH_VER_MAX; i++) { - if( ver.find(versionStrs[i]) != -1 ) { - mVersion = (SshVersion)i; - break; - } - } - - kdDebug(KSSHPROC) << "KSshPRocess::version(): version number = " - << mVersion << endl; - - if( mVersion == UNKNOWN_VER ) { - kdDebug(KSSHPROC) << "KSshProcess::version(): " - "Sorry, I don't know about this version of ssh" << endl; - mError = ERR_UNKNOWN_VERSION; - return UNKNOWN_VER; - } - - return mVersion; -} -/* -TQString KSshProcess::versionStr() { - if( mVersion == UNKNOWN_VER ) { - version(); - if( mVersion == UNKNOWN_VER ) - return TQString::null; - } - - return TQString::fromLatin1(versionStrs[mVersion]); -} -*/ - -bool KSshProcess::setOptions(const SshOptList& opts) { - kdDebug(KSSHPROC) << "KSshProcess::setOptions()" << endl; - mArgs.clear(); - SshOptListConstIterator it; - TQString cmd, subsystem; - mPassword = mUsername = mHost = TQString::null; - TQCString tmp; - for(it = opts.begin(); it != opts.end(); ++it) { - //kdDebug(KSSHPROC) << "opt.opt = " << (*it).opt << endl; - //kdDebug(KSSHPROC) << "opt.str = " << (*it).str << endl; - //kdDebug(KSSHPROC) << "opt.num = " << (*it).num << endl; - switch( (*it).opt ) { - case SSH_VERBOSE: - mArgs.append("-v"); - break; - - case SSH_SUBSYSTEM: - subsystem = (*it).str; - break; - - case SSH_PORT: - mArgs.append("-p"); - tmp.setNum((*it).num); - mArgs.append(tmp); - mPort = (*it).num; - break; - - case SSH_HOST: - mHost = (*it).str; - break; - - case SSH_USERNAME: - mArgs.append("-l"); - mArgs.append((*it).str.latin1()); - mUsername = (*it).str; - break; - - case SSH_PASSWD: - mPassword = (*it).str; - break; - - case SSH_PROTOCOL: - if( mVersion <= OPENSSH ) { - tmp = "Protocol="; - tmp += TQString::number((*it).num).latin1(); - mArgs.append("-o"); - mArgs.append(tmp); - } - else if( mVersion <= SSH ) { - if( (*it).num == 1 ) { - mArgs.append("-1"); - } - // else uses version 2 by default - } - break; - - case SSH_FORWARDX11: - tmp = "ForwardX11="; - tmp += (*it).boolean ? "yes" : "no"; - mArgs.append("-o"); - mArgs.append(tmp); - break; - - case SSH_FORWARDAGENT: - tmp = "ForwardAgent="; - tmp += (*it).boolean ? "yes" : "no"; - mArgs.append("-o"); - mArgs.append(tmp); - break; - - case SSH_ESCAPE_CHAR: - if( (*it).num == -1 ) - tmp = "none"; - else - tmp = (char)((*it).num); - mArgs.append("-e"); - mArgs.append(tmp); - break; - - case SSH_OPTION: - // don't allow NumberOfPasswordPrompts or StrictHostKeyChecking - // since KSshProcess depends on specific setting of these for - // preforming authentication correctly. - tmp = (*it).str.latin1(); - if( tmp.contains("NumberOfPasswordPrompts") || - tmp.contains("StrictHostKeyChecking") ) { - mError = ERR_INVALID_OPT; - return false; - } - else { - mArgs.append("-o"); - mArgs.append(tmp); - } - break; - - case SSH_COMMAND: - cmd = (*it).str; - break; - - default: - kdDebug(KSSHPROC) << "KSshProcess::setOptions(): " - "unrecognized ssh opt " << (*it).opt << endl; - } - } - - if( !subsystem.isEmpty() && !cmd.isEmpty() ) { - kdDebug(KSSHPROC) << "KSshProcess::setOptions(): " - "cannot use a subsystem and command at the same time" << endl; - mError = ERR_CMD_SUBSYS_CONFLICT; - mErrorMsg = i18n("Cannot specify a subsystem and command at the same time."); - return false; - } - - // These options govern the behavior of ssh and - // cannot be defined by the user - //mArgs.append("-o"); - //mArgs.append("StrictHostKeyChecking=ask"); - mArgs.append("-v"); // So we get a message that the - // connection was successful - if( mVersion <= OPENSSH ) { - // nothing - } - else if( mVersion <= SSH ) { - mArgs.append("-o"); // So we can check if the connection was successful - mArgs.append("AuthenticationSuccessMsg=yes"); - } - - if( mHost.isEmpty() ) { - kdDebug(KSSHPROC) << "KSshProcess::setOptions(): " - "a host name must be supplied" << endl; - return false; - } - else { - mArgs.append(mHost.latin1()); - } - - if( !subsystem.isEmpty() ) { - mArgs.append("-s"); - mArgs.append(subsystem.latin1()); - } - - if( !cmd.isEmpty() ) { - mArgs.append(cmd.latin1()); - } - - return true; -} - -void KSshProcess::printArgs() { - TQValueListIterator<TQCString> it; - for( it = mArgs.begin(); it != mArgs.end(); ++it) { - kdDebug(KSSHPROC) << "arg: " << *it << endl; - } -} - - -int KSshProcess::error(TQString& msg) { - kdDebug(KSSHPROC) << "KSshProcess::error()" << endl; - kdDebug() << mErrorMsg << endl; - msg = mErrorMsg; - return mError; -} - -void KSshProcess::kill(int signal) { - int pid = ssh.pid(); - - kdDebug(KSSHPROC) << "KSshProcess::kill(signal:" << signal - << "): ssh pid is " << pid << endl; - kdDebug(KSSHPROC) << "KSshPRocess::kill(): we are " - << (mConnected ? "" : "not ") << "connected" << endl; - kdDebug(KSSHPROC) << "KSshProcess::kill(): we are " - << (mRunning ? "" : "not ") << "running a ssh process" << endl; - - if( mRunning && pid > 1 ) { - // Kill the child process... - if ( ::kill(pid, signal) == 0 ) { - // clean up if we tried to kill the process - if( signal == SIGTERM || signal == SIGKILL ) { - while(waitpid(-1, NULL, WNOHANG) > 0); - mConnected = false; - mRunning = false; - } - } - else - kdDebug(KSSHPROC) << "KSshProcess::kill(): kill failed" << endl; - } - else - kdDebug(KSSHPROC) << "KSshProcess::kill(): " - "Refusing to kill ssh process" << endl; -} - - - -/** - * Try to open an ssh connection. - * SSH prints certain messages to certain file descriptiors: - * passwordPrompt - pty - * passphrasePrompt - pty - * authSuccessMsg - stderr (OpenSSH), - * authFailedMsg - stderr - * hostKeyMissing - stderr - * hostKeyChanged - stderr - * continuePrompt - stderr - * - * We will use a select to wait for a line on each descriptor. Then get - * each line that available and take action based on it. The type - * of messages we are looking for and the action we take on each - * message are: - * passwordPrompt - Return false, set error to ERR_NEED_PASSWD. - * On the next call to connect() we expect a password - * to be available. - * - * passpharsePrompt - Return false, set error to ERR_NEED_PASSPHRASE. - * On the next call to connect() we expect a - * passphrase to be available. - * - * authSuccessMsg - Return true, as we have successfully established a - * ssh connection. - * - * authFailedMsg - Return false, set error to ERR_AUTH_FAILED. We - * were unable to authenticate the connection given - * the available authentication information. - * - * hostKeyMissing - Return false, set error to ERR_NEW_HOST_KEY. Caller - * must call KSshProcess.acceptHostKey(bool) to accept - * or reject the key before calling connect() again. - * - * hostKeyChanged - Return false, set error to ERR_DIFF_HOST_KEY. Caller - * must call KSshProcess.acceptHostKey(bool) to accept - * or reject the key before calling connect() again. - * - * continuePrompt - Send 'yes' or 'no' to accept or reject a key, - * respectively. - * - */ - - -void KSshProcess::acceptHostKey(bool accept) { - kdDebug(KSSHPROC) << "KSshProcess::acceptHostKey(accept:" - << accept << ")" << endl; - mAcceptHostKey = accept; -} - -void KSshProcess::setPassword(TQString password) { - kdDebug(KSSHPROC) << "KSshProcess::setPassword(password:xxxxxxxx)" << endl; - mPassword = password; -} - -TQString KSshProcess::getLine() { - static TQStringList buffer; - TQString line = TQString::null; - TQCString ptyLine, errLine; - - if( buffer.empty() ) { - // PtyProcess buffers lines. First check that there - // isn't something on the PtyProces buffer or that there - // is not data ready to be read from the pty or stderr. - ptyLine = ssh.readLineFromPty(false); - errLine = ssh.readLineFromStderr(false); - - // If PtyProcess did have something for us, get it and - // place it in our line buffer. - if( ! ptyLine.isEmpty() ) { - buffer.prepend(TQString(ptyLine)); - } - - if( ! errLine.isEmpty() ) { - buffer.prepend(TQString(errLine)); - } - - // If we still don't have anything in our buffer so there must - // not be anything on the pty or stderr. Setup a select() - // to wait for some data from SSH. - // Hack around select() failure on newer systems - unsigned long milliseconds = 0; - while ((buffer.size() == 0) && (milliseconds < (60*1000))) { - //kdDebug(KSSHPROC) << "KSshProcess::getLine(): " << - // "Line buffer empty, calling select() to wait for data." << endl; - int errfd = ssh.stderrFd(); - int ptyfd = ssh.fd(); - fd_set rfds; - fd_set efds; - struct timeval tv; - - // find max file descriptor - int maxfd = ptyfd > errfd ? ptyfd : errfd; - - FD_ZERO(&rfds); - FD_SET(ptyfd, &rfds); // Add pty file descriptor - FD_SET(errfd, &rfds); // Add std error file descriptor - - FD_ZERO(&efds); - FD_SET(ptyfd, &efds); - FD_SET(errfd, &efds); - - tv.tv_sec = 60; tv.tv_usec = 0; // 60 second timeout - - // Wait for a message from ssh on stderr or the pty. - int ret = -1; - do - ret = ::select(maxfd+1, &rfds, NULL, &efds, &tv); - while( ret == -1 && errno == EINTR ); - - // Handle any errors from select - if( ret == 0 ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " << - "timed out waiting for a response" << endl; - mError = ERR_TIMED_OUT; - return TQString::null; - } - else if( ret == -1 ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - << "select error: " << strerror(errno) << endl; - mError = ERR_INTERNAL; - return TQString::null; - } - - // We are not respecting any type of order in which the - // lines were received. Who knows whether pty or stderr - // had data on it first. - if( FD_ISSET(ptyfd, &rfds) ) { - ptyLine = ssh.readLineFromPty(false); - if (ptyLine.size() > 0) { - buffer.prepend(TQString(ptyLine)); - } - //kdDebug(KSSHPROC) << "KSshProcess::getLine(): " - // "line from pty -" << ptyLine << endl; - } - - if( FD_ISSET(errfd, &rfds) ) { - errLine = ssh.readLineFromStderr(false); - if (errLine.size() > 0) { - buffer.prepend(TQString(errLine)); - } - //kdDebug(KSSHPROC) << "KSshProcess::getLine(): " - // "line from err -" << errLine << endl; - } - - if( FD_ISSET(ptyfd, &efds) ) { - kdDebug(KSSHPROC) << "KSshProcess::getLine(): " - "Exception on pty file descriptor." << endl; - } - - if( FD_ISSET(errfd, &efds) ) { - kdDebug(KSSHPROC) << "KSshProcess::getLine(): " - "Exception on std err file descriptor." << endl; - } - - if (buffer.size() == 0) { - milliseconds++; - usleep(1000); - } - } - } - - // We should have something in our buffer now. - // Return the last line. - //it = buffer.end(); - //line = *it; - //buffer.remove(it); - - line = buffer.last(); - buffer.pop_back(); - - if( line.isNull() && buffer.count() > 0 ) { - line = buffer.last(); - buffer.pop_back(); - } - -// kdDebug(KSSHPROC) << "KSshProcess::getLine(): " << -// buffer.count() << " lines in buffer" << endl; - kdDebug(KSSHPROC) << "KSshProcess::getLine(): " - "ssh: " << line << endl; - - - return line; -} - -// All the different states we could go through while trying to connect. -enum sshConnectState { - STATE_START, STATE_TRY_PASSWD, STATE_WAIT_PROMPT, STATE_NEW_KEY_CONTINUE, - STATE_DIFF_KEY_CONTINUE, STATE_FATAL, STATE_WAIT_CONTINUE_PROMPT, - STATE_SEND_CONTINUE, STATE_AUTH_FAILED, STATE_NEW_KEY_WAIT_CONTINUE, - STATE_DIFF_KEY_WAIT_CONTINUE, STATE_TRY_PASSPHRASE -}; - -// Print the state as a string. Good for debugging -const char* stateStr(int state) { - switch(state) { - case STATE_START: - return "STATE_START"; - case STATE_TRY_PASSWD: - return "STATE_TRY_PASSWD"; - case STATE_WAIT_PROMPT: - return "STATE_WAIT_PROMPT"; - case STATE_NEW_KEY_CONTINUE: - return "STATE_NEW_KEY_CONTINUE"; - case STATE_DIFF_KEY_CONTINUE: - return "STATE_DIFF_KEY_CONTINUE"; - case STATE_FATAL: - return "STATE_FATAL"; - case STATE_WAIT_CONTINUE_PROMPT: - return "STATE_WAIT_CONTINUE_PROMPT"; - case STATE_SEND_CONTINUE: - return "STATE_SEND_CONTINE"; - case STATE_AUTH_FAILED: - return "STATE_AUTH_FAILED"; - case STATE_NEW_KEY_WAIT_CONTINUE: - return "STATE_NEW_KEY_WAIT_CONTINUE"; - case STATE_DIFF_KEY_WAIT_CONTINUE: - return "STATE_DIFF_KEY_WAIT_CONTINUE"; - case STATE_TRY_PASSPHRASE: - return "STATE_TRY_PASSPHRASE"; - } - return "UNKNOWN"; -} - -bool KSshProcess::connect() { - if( mVersion == UNKNOWN_VER ) { - // we don't know the ssh version yet, so find out - version(); - if( mVersion == -1 ) { - return false; - } - } - - // We'll put a limit on the number of state transitions - // to ensure we don't go out of control. - int transitionLimit = 500; - - while(--transitionLimit) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - << "Connect state " << stateStr(mConnectState) << endl; - - TQString line; // a line from ssh - TQString msgBuf; // buffer for important messages from ssh - // which are to be returned to the user - - switch(mConnectState) { - // STATE_START: - // Executes the ssh binary with the options provided. If no options - // have been specified, sets error and returns false. Continue to - // state 1 if execution is successful, otherwise set error and - // return false. - case STATE_START: - // reset some key values to safe values - mAcceptHostKey = false; - mKeyFingerprint = TQString::null; - mKnownHostsFile = TQString::null; - - if( mArgs.isEmpty() ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): ssh options " - "need to be set first using setArgs()" << endl; - mError = ERR_NO_OPTIONS; - mErrorMsg = i18n("No options provided for ssh execution."); - return false; - } - - if( ssh.exec(mSshPath.latin1(), mArgs) ) { - kdDebug(KSSHPROC) << - "KSshProcess::connect(): ssh exec failed" << endl; - mError = ERR_CANNOT_LAUNCH; - mErrorMsg = i18n("Failed to execute ssh process."); - return false; - } - - kdDebug(KSSHPROC) << "KSshPRocess::connect(): ssh pid = " << ssh.pid() << endl; - - // set flag to indicate what have started a ssh process - mRunning = true; - mConnectState = STATE_WAIT_PROMPT; - break; - - // STATE_WAIT_PROMPT: - // Get a line of input from the ssh process. Check the contents - // of the line to determine the next state. Ignore the line - // if we don't recognize its contents. If the line contains - // the continue prompt, we have an error since we should never - // get that line in this state. Set ERR_INVALID_STATE error - // and return false. - case STATE_WAIT_PROMPT: - line = getLine(); - if( line.isNull() ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - "Got null line in STATE_WAIT_PROMPT." << endl; - mError = ERR_INTERACT; - mErrorMsg = - i18n("Error encountered while talking to ssh."); - mConnectState = STATE_FATAL; - } - else if( line.find(TQString::fromLatin1(passwordPrompt[mVersion]), 0, false) != -1 ) { - mConnectState = STATE_TRY_PASSWD; - } - else if( line.find(passphrasePrompt[mVersion]) != -1 ) { - mConnectState = STATE_TRY_PASSPHRASE; - } - else if( line.find(authSuccessMsg[mVersion]) != -1 ) { - return true; - } - else if( line.find(authFailedMsg[mVersion]) != -1 - && line.find(tryAgainMsg[mVersion]) == -1 ) { - mConnectState = STATE_AUTH_FAILED; - } - else if( line.find(hostKeyMissingMsg[mVersion]) != -1 ) { - mConnectState = STATE_NEW_KEY_WAIT_CONTINUE; - } - else if( line.find(hostKeyChangedMsg[mVersion]) != -1 ) { - mConnectState = STATE_DIFF_KEY_WAIT_CONTINUE; - } - else if( line.find(continuePrompt[mVersion]) != -1 ) { - //mConnectState = STATE_SEND_CONTINUE; - kdDebug(KSSHPROC) << "KSshProcess:connect(): " - "Got continue prompt where we shouldn't (STATE_WAIT_PROMPT)" - << endl; - mError = ERR_INTERACT; - mErrorMsg = - i18n("Error encountered while talking to ssh."); - } - else if( line.find(connectionClosedMsg[mVersion]) != -1 ) { - mConnectState = STATE_FATAL; - mError = ERR_CLOSED_BY_REMOTE_HOST; - mErrorMsg = i18n("Connection closed by remote host."); - } - else if( line.find(changeHostKeyOnDiskPrompt[mVersion]) != -1 ) { - // always say yes to this. It always comes after commerical ssh - // prints a "continue to connect prompt". We assume that if the - // user choose to continue, then they also want to save the - // host key to disk. - ssh.writeLine("yes"); - } - else { - // ignore line - } - break; - - // STATE_TRY_PASSWD: - // If we have password send it to the ssh process, else - // set error ERR_NEED_PASSWD and return false to the caller. - // The caller then must then call KSshProcess::setPassword(TQString) - // before calling KSshProcess::connect() again. - // - // Almost exactly liek STATE_TRY_PASSPHRASE. Check there if you - // make changes here. - case STATE_TRY_PASSWD: - // We have a password prompt waiting for us to supply - // a password. Send that password to ssh. If the caller - // did not supply a password like we asked, then ask - // again. - if( !mPassword.isEmpty() ) { -// ssh.WaitSlave(); - ssh.writeLine(mPassword.latin1()); - - // Overwrite the password so it isn't in memory. - mPassword.fill(TQChar('X')); - - // Set the password to null so we will request another - // password if this one fails. - mPassword = TQString::null; - - mConnectState = STATE_WAIT_PROMPT; - } - else { - kdDebug(KSSHPROC) << "KSshProcess::connect() " - "Need password from caller." << endl; - // The caller needs to supply a password before - // connecting can continue. - mError = ERR_NEED_PASSWD; - mErrorMsg = i18n("Please supply a password."); - mConnectState = STATE_TRY_PASSWD; - return false; - } - break; - - // STATE_TRY_KEY_PASSPHRASE: - // If we have passphrase send it to the ssh process, else - // set error ERR_NEED_PASSPHRASE and return false to the caller. - // The caller then must then call KSshProcess::setPassword(TQString) - // before calling KSshProcess::connect() again. - // - // Almost exactly like STATE_TRY_PASSWD. The only difference is - // the error we set if we don't have a passphrase. We duplicate - // this code to keep in the spirit of the state machine. - case STATE_TRY_PASSPHRASE: - // We have a passphrase prompt waiting for us to supply - // a passphrase. Send that passphrase to ssh. If the caller - // did not supply a passphrase like we asked, then ask - // again. - if( !mPassword.isEmpty() ) { -// ssh.WaitSlave(); - ssh.writeLine(mPassword.latin1()); - - // Overwrite the password so it isn't in memory. - mPassword.fill(TQChar('X')); - - // Set the password to null so we will request another - // password if this one fails. - mPassword = TQString::null; - - mConnectState = STATE_WAIT_PROMPT; - } - else { - kdDebug(KSSHPROC) << "KSshProcess::connect() " - "Need passphrase from caller." << endl; - // The caller needs to supply a passphrase before - // connecting can continue. - mError = ERR_NEED_PASSPHRASE; - mErrorMsg = i18n("Please supply the passphrase for " - "your SSH private key."); - mConnectState = STATE_TRY_PASSPHRASE; - return false; - } - break; - - // STATE_AUTH_FAILED: - // Authentication has failed. Tell the caller by setting the - // ERR_AUTH_FAILED error and returning false. If - // auth has failed then ssh should have exited, but - // we will kill it to make sure. - case STATE_AUTH_FAILED: - mError = ERR_AUTH_FAILED; - mErrorMsg = i18n("Authentication to %1 failed").arg(mHost); - mConnectState = STATE_FATAL; - break; - - // STATE_NEW_KEY_WAIT_CONTINUE: - // Grab lines from ssh until we get a continue prompt or a auth - // denied. We will get the later if StrictHostKeyChecking is set - // to yes. Go to STATE_NEW_KEY_CONTINUE if we get a continue prompt. - case STATE_NEW_KEY_WAIT_CONTINUE: - line = getLine(); - if( line.isNull() ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - "Got null line in STATE_NEW_KEY_WAIT_CONTINUE." << endl; - mError = ERR_INTERACT; - mErrorMsg = - i18n("Error encountered while talking to ssh."); - mConnectState = STATE_FATAL; - } - else if( (line.find(authFailedMsg[mVersion]) != -1 - && line.find(tryAgainMsg[mVersion]) == -1) - || line.find(hostKeyVerifyFailedMsg[mVersion]) != -1 ) { - mError = ERR_AUTH_FAILED_NEW_KEY; - mErrorMsg = i18n( - "The identity of the remote host '%1' could not be verified " - "because the host's key is not in the \"known hosts\" file." - ).arg(mHost); - - if( mKnownHostsFile.isEmpty() ) { - mErrorMsg += i18n( - " Manually, add the host's key to the \"known hosts\" " - "file or contact your administrator." - ); - } - else { - mErrorMsg += i18n( - " Manually, add the host's key to %1 " - "or contact your administrator." - ).arg(mKnownHostsFile); - } - - mConnectState = STATE_FATAL; - } - else if( line.find(continuePrompt[mVersion]) != -1 ) { - mConnectState = STATE_NEW_KEY_CONTINUE; - } - else if( line.find(connectionClosedMsg[mVersion]) != -1 ) { - mConnectState = STATE_FATAL; - mError = ERR_CLOSED_BY_REMOTE_HOST; - mErrorMsg = i18n("Connection closed by remote host."); - } - else if( line.find(keyFingerprintMsg[mVersion]) != -1 ) { - mKeyFingerprint = keyFingerprintMsg[mVersion].cap(); - kdDebug(KSSHPROC) << "Found key fingerprint: " << mKeyFingerprint << endl; - mConnectState = STATE_NEW_KEY_WAIT_CONTINUE; - } - else { - // ignore line - } - break; - - - // STATE_NEW_KEY_CONTINUE: - // We got a continue prompt for the new key message. Set the error - // message to reflect this, return false and hope for caller response. - case STATE_NEW_KEY_CONTINUE: - mError = ERR_NEW_HOST_KEY; - mErrorMsg = i18n( - "The identity of the remote host '%1' could not be " - "verified. The host's key fingerprint is:\n%2\nYou should " - "verify the fingerprint with the host's administrator before " - "connecting.\n\n" - "Would you like to accept the host's key and connect anyway? " - ).arg(mHost).arg(mKeyFingerprint); - mConnectState = STATE_SEND_CONTINUE; - return false; - - // STATE_DIFF_KEY_WAIT_CONTINUE: - // Grab lines from ssh until we get a continue prompt or a auth - // denied. We will get the later if StrictHostKeyChecking is set - // to yes. Go to STATE_DIFF_KEY_CONTINUE if we get a continue prompt. - case STATE_DIFF_KEY_WAIT_CONTINUE: - line = getLine(); - if( line.isNull() ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - "Got null line in STATE_DIFF_KEY_WAIT_CONTINUE." << endl; - mError = ERR_INTERACT; - mErrorMsg = - i18n("Error encountered while talking to ssh."); - mConnectState = STATE_FATAL; - } - else if( (line.find(authFailedMsg[mVersion]) != -1 - && line.find(tryAgainMsg[mVersion]) == -1) - || line.find(hostKeyVerifyFailedMsg[mVersion]) != -1 ) { - mError = ERR_AUTH_FAILED_DIFF_KEY; - mErrorMsg = i18n( - "WARNING: The identity of the remote host '%1' has changed!\n\n" - "Someone could be eavesdropping on your connection, or the " - "administrator may have just changed the host's key. " - "Either way, you should verify the host's key fingerprint with the host's " - "administrator. The key fingerprint is:\n%2\n" - "Add the correct host key to \"%3\" to " - "get rid of this message." - ).arg(mHost).arg(mKeyFingerprint).arg(mKnownHostsFile); - mConnectState = STATE_FATAL; - } - else if( line.find(continuePrompt[mVersion]) != -1 ) { - mConnectState = STATE_DIFF_KEY_CONTINUE; - } - else if( line.find(keyFingerprintMsg[mVersion]) != -1 ) { - mKeyFingerprint = keyFingerprintMsg[mVersion].cap(); - kdDebug(KSSHPROC) << "Found key fingerprint: " << mKeyFingerprint << endl; - mConnectState = STATE_DIFF_KEY_WAIT_CONTINUE; - } - else if( line.find(knownHostsFileMsg[mVersion]) != -1 ) { - mKnownHostsFile = (knownHostsFileMsg[mVersion]).cap(1); - kdDebug(KSSHPROC) << "Found known hosts file name: " << mKnownHostsFile << endl; - mConnectState = STATE_DIFF_KEY_WAIT_CONTINUE; - } - else { - // ignore line - } - break; - - // STATE_DIFF_KEY_CONTINUE: - // We got a continue prompt for the different key message. - // Set ERR_DIFF_HOST_KEY error - // and return false to signal need to caller action. - case STATE_DIFF_KEY_CONTINUE: - mError = ERR_DIFF_HOST_KEY; - mErrorMsg = i18n( - "WARNING: The identity of the remote host '%1' has changed!\n\n" - "Someone could be eavesdropping on your connection, or the " - "administrator may have just changed the host's key. " - "Either way, you should verify the host's key fingerprint with the host's " - "administrator before connecting. The key fingerprint is:\n%2\n\n" - "Would you like to accept the host's new key and connect anyway?" - ).arg(mHost).arg(mKeyFingerprint); - mConnectState = STATE_SEND_CONTINUE; - return false; - - // STATE_SEND_CONTINUE: - // We found a continue prompt. Send our answer. - case STATE_SEND_CONTINUE: - if( mAcceptHostKey ) { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - "host key accepted" << endl; - ssh.writeLine("yes"); - mConnectState = STATE_WAIT_PROMPT; - } - else { - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - "host key rejected" << endl; - ssh.writeLine("no"); - mError = ERR_HOST_KEY_REJECTED; - mErrorMsg = i18n("Host key was rejected."); - mConnectState = STATE_FATAL; - } - break; - - // STATE_FATAL: - // Something bad happened that we cannot recover from. - // Kill the ssh process and set flags to show we have - // ended the connection and killed ssh. - // - // mError and mErrorMsg should be set by the immediately - // previous state. - case STATE_FATAL: - kill(); - mConnected = false; - mRunning = false; - mConnectState = STATE_START; - // mError, mErroMsg set by last state - return false; - - default: - kdDebug(KSSHPROC) << "KSshProcess::connect(): " - "Invalid state number - " << mConnectState << endl; - mError = ERR_INVALID_STATE; - mConnectState = STATE_FATAL; - } - } - - // we should never get here - kdDebug(KSSHPROC) << "KSshProcess::connect(): " << - "After switch(). We shouldn't be here." << endl; - mError = ERR_INTERNAL; - return false; -} - -void KSshProcess::disconnect() { - kill(); - mConnected = false; - mRunning = false; - mConnectState = STATE_START; -} - diff --git a/tdeioslave/sftp/ksshprocess.h b/tdeioslave/sftp/ksshprocess.h deleted file mode 100644 index 5130628e4..000000000 --- a/tdeioslave/sftp/ksshprocess.h +++ /dev/null @@ -1,623 +0,0 @@ -/*************************************************************************** - ksshprocess.h - description - ------------------- - begin : Tue Jul 31 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef KSSHPROCESS_H -#define KSSHPROCESS_H - -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> - -#include <tqvaluelist.h> - -#include <kdebug.h> - -#include "process.h" - -#define KSSHPROC 7120 - -/** - * Provides version independent access to ssh. Currently supported - * versions of SSH are: - * OpenSSH 2.9p1 - * OpenSSH 2.9p2 - * OpenSSH 3.0 - * OpenSSH 3.1 - * Commercial SSH 3.0.0 - * Other versions of OpenSSH and commerical SSH will probably work also. - * - * To setup a SSH connection first create a list of options to use and tell - * KSshProcess about your options. Then start the ssh connection. Once the - * connection is setup use the stdin, stdout, stderr, and pty file descriptors - * to communicate with ssh. For a detailed example of how to use, see - * ksshprocesstest.cpp. - * - * @author Lucas Fisher - * - * Example: Connect to ssh server on localhost - * KSshProcess::SshOpt opt; - * KSshProcess::SshOptList options; - * - * opt.opt = KSshProcess::SSH_HOST; - * opt.str = "localhost"; - * options.append(opt); - * - * opt.opt = KSshProcess::SSH_USERNAME; - * opt.str = "me"; - * options.append(opt); - * - * KSshProcess ssh; - * if( !ssh.setOptions(options) ) { - * int err = ssh.error(); - * // process error - * return false; - * } - * - * int err; - * TQString errMsg; - * while( !ssh.connect() ) { - * err = ssh.error(errMsg); - * - * switch( err ) { - * case KSshProcess::ERR_NEW_HOST_KEY: - * case KSshProcess::ERR_DIFF_HOST_KEY: - * // ask user to accept key - * if( acceptHostKey ) { - * ssh.acceptKey(true); - * } - * break; - * - * case KSshProcess::ERR_NEED_PASSWORD: - * // ask user for password - * ssh.password(userPassword); - * break; - * - * case KSshProcess::ERR_NEED_KEY_PASSPHRASE: - * // ask user for their key passphrase - * ssh.keyPassphrase(keyPassphrase); - * break; - * - * default: - * // somethings wrong, alert user - * return; - * } - * } - * // We have an open ssh connection to localhost - * - */ - -class KSshProcess { -public: - /** - * SSH Option - * - * Stores SSH options for use with KSshProcess. - * - * SSH options are configured much like UDS entries. - * Each option is assigned a constant and a string, bool, - * or number is assigned based on the option. - * - * @author Lucas Fisher (ljfisher@iastate.edu) - */ - class SshOpt { - public: - TQ_UINT32 opt; - TQString str; - TQ_INT32 num; - bool boolean; - }; - - /** - * List of SshOptions and associated iterators - */ - typedef TQValueList<SshOpt> SshOptList; - typedef TQValueListIterator<SshOpt> SshOptListIterator; - typedef TQValueListConstIterator<SshOpt> SshOptListConstIterator; - - /** - * Ssh versions supported by KSshProcess. Subject to change - * at any time. - */ - enum SshVersion { - OPENSSH_3_6, - OPENSSH, - SSH, - SSH_VER_MAX, - UNKNOWN_VER - }; - - /** - * SSH options supported by KSshProcess. Set SshOpt::opt to one of these - * values. - */ - // we cannot do this like UDSAtomType (ORing the type with the name) because - // we have too many options for ssh and not enough bits. - enum SshOptType { - /** - * Request server to invoke subsystem. (str) - */ - SSH_SUBSYSTEM, - /** - * Connect to port on the server. (num) - */ - SSH_PORT, - /** - * Connect to host. (str) - */ - SSH_HOST, - /** - * connect using this username. (str) - */ - SSH_USERNAME, - /** - * connect using this password. (str) - */ - SSH_PASSWD, - /** - * connect using this version of the SSH protocol. num == 1 or 2 - */ - SSH_PROTOCOL, - /** - * whether to forward X11 connections. (boolean) - */ - SSH_FORWARDX11, - /** - * whether to do agent forwarding. (boolean) - */ - SSH_FORWARDAGENT, - /** - * use as escape character. 0 for none (num) - */ - SSH_ESCAPE_CHAR, - /** - * command for ssh to perform once it is connected (str) - */ - SSH_COMMAND, - /** - * Set ssh verbosity. This may be added multiple times. It may also cause KSSHProcess - * to fail since we don't understand all the debug messages. - */ - SSH_VERBOSE, - /** - * Set a ssh option as one would find in the ssh_config file - * The str member should be set to 'optName value' - */ - SSH_OPTION, - /** - * Set some other option not supported by KSSHProcess. The option should - * be specified in the str member of SshOpt. Careful with this since - * not all versions of SSH support the same options. - */ - SSH_OTHER, - SSH_OPT_MAX // always last - }; // that's all for now - - /** - * Errors that KSshProcess can encounter. When a member function returns - * false, call error() to retrieve one of these error codes. - */ - enum SshError { - /** - * Don't recognize the ssh version - */ - ERR_UNKNOWN_VERSION, - /** - * Cannot lauch ssh client - */ - ERR_CANNOT_LAUNCH, - /** - * Interaction with the ssh client failed. This happens when we can't - * find the password prompt or something similar - */ - ERR_INTERACT, - /** - * Arguments for both a remotely executed subsystem and command were provide. - * Only one or the other may be used - */ - ERR_CMD_SUBSYS_CONFLICT, - /** - * No password was supplied - */ - ERR_NEED_PASSWD, - /** - * No passphrase was supplied. - */ - ERR_NEED_PASSPHRASE, - /** - * No usename was supplied - */ - ERR_NEED_USERNAME, - /** - * Timed out waiting for a response from ssh or the server - */ - ERR_TIMED_OUT, - /** - * Internal error, probably from a system call - */ - ERR_INTERNAL, - /** - * ssh was disconnect from the host - */ - ERR_DISCONNECTED, - /** - * No ssh options have been set. Call setArgs() before calling connect. - */ - ERR_NO_OPTIONS, - /** - * A host key was received from an unknown host. - * Call connect() with the acceptHostKey argument to accept the key. - */ - ERR_NEW_HOST_KEY, - /** - * A host key different from what is stored in the user's known_hosts file - * has be received. This is an indication of an attack - */ - ERR_DIFF_HOST_KEY, - /** - * A new or different host key was rejected by the caller. The ssh - * connection was terminated and the ssh process killed. - */ - ERR_HOST_KEY_REJECTED, - /** - * An invalid option was found in the SSH option list - */ - ERR_INVALID_OPT, - /** - * SSH accepted host key without prompting user. - */ - ERR_ACCEPTED_KEY, - /** - * Authentication failed - */ - ERR_AUTH_FAILED, - /** - * Authentication failed because a new host key was detected and - * SSH is configured with strict host key checking enabled. - */ - ERR_AUTH_FAILED_NEW_KEY, - /** - * Authentication failed because a changed host key was detected and - * SSH is configured with strict host key checking enabled. - */ - ERR_AUTH_FAILED_DIFF_KEY, - /** - * The remote host closed the connection for unknown reasons. - */ - ERR_CLOSED_BY_REMOTE_HOST, - /** - * We have no idea what happened - */ - ERR_UNKNOWN, - /** - * The connect state machine entered an invalid state. - */ - ERR_INVALID_STATE, - ERR_MAX - }; - - /** - * Initialize a SSH process using the first SSH binary found in the PATH - */ - KSshProcess(); - - /** - * Initialize a SSH process using the specified SSH binary. - * @param pathToSsh The fully qualified path name of the ssh binary - * KSshProcess should use to setup a SSH connection. - */ - KSshProcess(TQString pathToSsh); - ~KSshProcess(); - - /** - * Set the ssh binary KSshProcess should use. This will only affect the - * next ssh connection attempt using this instance. - * - * @param pathToSsh Full path to the ssh binary. - * - * @return True if the ssh binary is found and KSshProcess - * recognizes the version. - * - */ - bool setSshPath(TQString pathToSsh); - - /** - * Get the ssh version. - * - * @return The ssh version or -1 if KSshProcess does not recognize - * the ssh version. The returned value corresponds to the - * member of the SshVersion enum. - */ - SshVersion version(); - - /** - * Get a string describing the ssh version - * - * @return A string describing the ssh version recognized by KSshProcess - */ - //TQString versionStr(); - - /** - * Get the last error encountered by KSshProcess. - * - * @param msg Set to the error message, if any, outputted by ssh when it is run. - * - * @return The error number. See SshError for descriptions. - */ - int error(TQString& msg); - - /** - * Get the last error encountered by KSshProcess. - * @return The error number. See SshError for descriptions. - */ - int error() { return mError; } - - TQString errorMsg() { return mErrorMsg; } - - /** - * Send a signal to the ssh process. Do not use this to end the - * ssh connection as it will not correctly reset the internal - * state of the KSshProcess object. Use KSshProcess::disconnect() - * instead. - * - * @param signal The signal to send to the ssh process. See 'kill -l' - * for a list of possible signals. - * The default signal is SIGKILL which kills ssh. - * - */ - void kill(int signal = SIGKILL); - - /** - * The pid of the ssh process started by this instance of KSshProcess. - * Only valid if KSshProcess::running() returns true; - * - * @return The pid of the running ssh process. - */ - int pid() { return ssh.pid(); } - - /** - * Whether a ssh connection has been established with a - * remote host. A establish connection means ssh has successfully - * authenticated with the remote host and user data can be transfered - * between the local and remote host. This cannot return - * true unless the most recent call to KSshProccess::connect() returned true. - * - * @return True if a ssh connection has been established with a remote - * host. False otherwise. - */ - bool connected() { return mConnected; } - - /** - * Whether a ssh process is currently running. This only indicates - * if a ssh process has been started and is still running. It does not - * tell if authentication has been successful. This may return true - * even if the most recent call to KSshProcess::connect() returned false. - * - * @return True if a ssh process started by this instance of KSshProcess - * is running. False otherwise. - */ - bool running() { return mRunning; } - - /** - * Print the command line arguments ssh is run with using kdDebug. - */ - void printArgs(); - - /** - * Set the SSH options. - * This must be called before connect(). See SshOptType for a list of - * supported ssh options. The required options are SSH_USERNAME - * and SSH_HOST. - * - * To reset the saved options, just recall setOptions() again with - * a different options list. - * - * @param opts A list of SshOpt objects specifying the ssh options. - * - * @return True if all options are valid. False if unrecognized options - * or a required option is missing. Call error() - * for details. - * - */ - bool setOptions(const SshOptList& opts); - - /** - * Create a ssh connection based on the options provided by setOptions(). - * Sets one of the following error codes on failure: - * <ul> - * <li>ERR_NO_OPTIONS</li> - * <li>ERR_CANNOT_LAUNCH</li> - * <li>ERR_INVALID_STATE</li> - * <li>ERR_NEED_PASSWD</li> - * <li>ERR_AUTH_FAILED</li> - * <li>ERR_NEW_HOST_KEY</li> - * <li>ERR_KEY_ACCEPTED</li> - * <li>ERR_DIFF_HOST_KEY</li> - * <li>ERR_INTERNAL</li> - * <li>ERR_INTERACT</li> - * </ul> - * - * @param acceptHostKey When true KSshProcess will automatically accept - * unrecognized or changed host keys. - * - * @return True if the ssh connection is successful. False if the connection - * fails. Call error() to get the reason for the failure. - */ - bool connect(); - - - /** - * Disconnect ssh from the host. This kills the ssh process and - * resets the internal state of this KSshProcess object. After a - * disconnect, the same KSshProcess can be used to connect to a - * host. - */ - void disconnect(); - - /** - * Call to respond to a ERR_NEW_HOST_KEY or ERR_DIFF_HOST_KEY error. - * - * @param accept True to accept the host key, false to not accept the - * host key and kill ssh. - * - */ - void acceptHostKey(bool accept); - - /** - * Call to respond to a ERR_NEED_PASSWD or ERR_NEED_PASSPHRASE error. - * - * @param password The user password to give ssh. - */ - void setPassword(TQString password); - - /** - * Access to standard in and out of the ssh process. - * - * @return The file description for stdin and stdout of the ssh process. - */ - int stdioFd() { return ssh.stdioFd(); } - - /** - * Access to standard error of the ssh process. - * - * @return The file descriptior for stderr of the ssh process. - */ - int stderrFd() { return ssh.stderrFd(); } - - /** - * Access the pty to which the ssh process is attached. - * - * @return The file descriptor of pty to which ssh is attached. - */ - int pty() { return ssh.fd(); } -private: - /** - * Path the the ssh binary. - */ - TQString mSshPath; - - /** - * SSH version. This is an index into the supported SSH - * versions array, and the various messages arrays. - */ - SshVersion mVersion; - - /** - * User's password. Zero this out when it is no longer needed. - */ - TQString mPassword; - - /** - * User's username. - */ - TQString mUsername; - - /** - * Name of host we are connecting to. - */ - TQString mHost; - - /** - * Accept new or changed host keys if true. - */ - bool mAcceptHostKey; - - /** - * Flag to tell use if we have an open, authenticated ssh - * session going. - */ - bool mConnected; - - /** - * Flag to tell us if we have started a ssh process, we use this - * to make sure we kill ssh before going away. - */ - bool mRunning; - - /** - * Save any key fingerprint msg from ssh so we can present - * it to the caller. - */ - TQString mKeyFingerprint; - - /** - * The location of the known host key file. We grab this from - * any error messages ssh prints out. - */ - TQString mKnownHostsFile; - - /** - * The state of our connect state machine. - */ - int mConnectState; - - /** - * Port on on which the target ssh server is listening. - */ - int mPort; - - /** - * The last error number encountered. This is only valid for the - * last error. - */ - SshError mError; - - /** - * An error message that corresponds to the error number set in - * mError. Optional. - */ - TQString mErrorMsg; - - /** - * Interface to the SSH process we ceate. Handles communication - * to and from the SSH process using stdin, stdout, stderr, and - * pty. - */ - MyPtyProcess ssh; - - /** - * List of arguments we start SSH with. - */ - QCStringList mArgs; - void init(); - - /** - * Handler to clean up when ssh process terminates. - */ - static void SIGCHLD_handler(int signo); - void installSignalHandlers(); - void removeSignalHandlers(); - - TQString getLine(); - - static TQRegExp versionStrs[]; - static const char * const passwordPrompt[]; - static const char * const passphrasePrompt[]; - static const char * const authSuccessMsg[]; - static const char * const authFailedMsg[]; - static TQRegExp hostKeyMissingMsg[]; - static const char * const hostKeyChangedMsg[]; - static const char * const continuePrompt[]; - static const char * const hostKeyAcceptedMsg[]; - static const char * const tryAgainMsg[]; - static TQRegExp hostKeyVerifyFailedMsg[]; - static const char * const connectionClosedMsg[]; - static const char * const changeHostKeyOnDiskPrompt[]; - static TQRegExp keyFingerprintMsg[]; - static TQRegExp knownHostsFileMsg[]; -}; -#endif diff --git a/tdeioslave/sftp/ksshprocesstest.cpp b/tdeioslave/sftp/ksshprocesstest.cpp deleted file mode 100644 index 59dbf58c7..000000000 --- a/tdeioslave/sftp/ksshprocesstest.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "ksshprocess.h" -#include <iostream> - -using namespace std; - -int main(int argc, char *argv[]) { - - if( argc < 5 ) { - cout << "Usage: " << argv[0] << - " <ssh path> <host> <username> <password>" << endl; - return 1; - } - - KSshProcess ssh(argv[1]); - cout << ssh.version() << endl; - - KSshProcess::SshOptList opts; - KSshProcess::SshOpt opt; - - opt.opt = KSshProcess::SSH_PORT; - opt.num = 22; - opts.append(opt); - - opt.opt = KSshProcess::SSH_HOST; - opt.str = TQString(argv[2]); - opts.append(opt); - - opt.opt = KSshProcess::SSH_USERNAME; - opt.str = TQString(argv[3]); - opts.append(opt); - -// opt.opt = KSshProcess::SSH_PASSWD; -// opt.str = TQString(argv[4]); -// opts.append(opt); - - if( !ssh.setOptions(opts) ) { - cout << "ksshprocesstest: setOptions failed" << endl; - return -1; - } - - ssh.printArgs(); - - bool stop = false; - bool connected; - char buf[256]; - char c; - while( !stop && !(connected = ssh.connect()) ) { - cout << "ksshprocesstest: Error num - " << ssh.error() << endl; - cout << "ksshprocesstest: Error msg - " << ssh.errorMsg().latin1() << endl; - switch( ssh.error() ) { - case KSshProcess::ERR_NEED_PASSWD: - case KSshProcess::ERR_NEED_PASSPHRASE: - cout << "Password: "; - cin >> buf; - cout << "password is " << buf << endl; - ssh.setPassword(TQString(buf)); - break; - case KSshProcess::ERR_NEW_HOST_KEY: - case KSshProcess::ERR_DIFF_HOST_KEY: - cout << "Accept host key? (y/n): "; - cin >> c; - cout << "Answered " << c << endl; - ssh.acceptHostKey(c == 'y' ? true : false); - break; - case KSshProcess::ERR_AUTH_FAILED: - cout << "ksshprocesstest: auth failed." << endl; - stop = true; - break; - case KSshProcess::ERR_AUTH_FAILED_NEW_KEY: - cout << "ksshprocesstest: auth failed because of new key." << endl; - stop = true; - break; - case KSshProcess::ERR_AUTH_FAILED_DIFF_KEY: - cout << "ksshprocesstest: auth failed because of changed key." << endl; - stop = true; - break; - - case KSshProcess::ERR_INTERACT: - case KSshProcess::ERR_INTERNAL: - case KSshProcess::ERR_UNKNOWN: - case KSshProcess::ERR_INVALID_STATE: - case KSshProcess::ERR_CANNOT_LAUNCH: - case KSshProcess::ERR_HOST_KEY_REJECTED: - cout << "ksshprocesstest: FATAL ERROR" << endl; - stop = true; - break; - - } - } - - if( connected ) { - cout << "ksshprocesstest: Successfully connected to " << argv[2] << endl; - } - else { - cout << "ksshprocesstest: Connect to " << argv[2] << " failed." << endl; - } - -} diff --git a/tdeioslave/sftp/process.cpp b/tdeioslave/sftp/process.cpp deleted file mode 100644 index bcb686df0..000000000 --- a/tdeioslave/sftp/process.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> - * - * This file contains code from TEShell.C of the KDE konsole. - * Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> - * - * This is free software; you can use this library under the GNU Library - * General Public License, version 2. See the file "COPYING.LIB" for the - * exact licensing terms. - * - * process.cpp: Functionality to build a front end to password asking - * terminal programs. - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <string.h> -#include <termios.h> -#include <signal.h> - -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/socket.h> - -#if defined(__SVR4) && defined(sun) -#include <stropts.h> -#include <sys/stream.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> // Needed on some systems. -#endif - -#include <tqglobal.h> -#include <tqcstring.h> -#include <tqfile.h> - -#include <kdebug.h> -#include <kstandarddirs.h> - -#include "process.h" -#include <tdesu/tdesu_pty.h> -#include <tdesu/kcookie.h> - - -MyPtyProcess::MyPtyProcess() -{ - m_bTerminal = false; - m_bErase = false; - m_pPTY = 0L; - m_Pid = -1; - m_Fd = -1; -} - - -int MyPtyProcess::init() -{ - delete m_pPTY; - m_pPTY = new PTY(); - m_Fd = m_pPTY->getpt(); - if (m_Fd < 0) - return -1; - if ((m_pPTY->grantpt() < 0) || (m_pPTY->unlockpt() < 0)) - { - kdError(PTYPROC) << k_lineinfo << "Master setup failed.\n" << endl; - m_Fd = -1; - return -1; - } - m_TTY = m_pPTY->ptsname(); - m_stdoutBuf.resize(0); - m_stderrBuf.resize(0); - m_ptyBuf.resize(0); - return 0; -} - - -MyPtyProcess::~MyPtyProcess() -{ - delete m_pPTY; -} - - -/* - * Read one line of input. The terminal is in canonical mode, so you always - * read a line at at time, but it's possible to receive multiple lines in - * one time. - */ - - -TQCString MyPtyProcess::readLineFrom(int fd, TQCString& inbuf, bool block) -{ - int pos; - TQCString ret; - - if (!inbuf.isEmpty()) - { - - pos = inbuf.find('\n'); - - if (pos == -1) - { - ret = inbuf; - inbuf.resize(0); - } else - { - ret = inbuf.left(pos); - inbuf = inbuf.mid(pos+1); - } - return ret; - - } - - int flags = fcntl(fd, F_GETFL); - if (flags < 0) - { - kdError(PTYPROC) << k_lineinfo << "fcntl(F_GETFL): " << perror << "\n"; - return ret; - } - if (block) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, flags) < 0) - { - kdError(PTYPROC) << k_lineinfo << "fcntl(F_SETFL): " << perror << "\n"; - return ret; - } - - int nbytes; - char buf[256]; - while (1) - { - nbytes = read(fd, buf, 255); - if (nbytes == -1) - { - if (errno == EINTR) - continue; - else break; - } - if (nbytes == 0) - break; // eof - - buf[nbytes] = '\000'; - inbuf += buf; - - pos = inbuf.find('\n'); - if (pos == -1) - { - ret = inbuf; - inbuf.resize(0); - } else - { - ret = inbuf.left(pos); - inbuf = inbuf.mid(pos+1); - } - break; - - } - - return ret; -} - -void MyPtyProcess::writeLine(TQCString line, bool addnl) -{ - if (!line.isEmpty()) - write(m_Fd, line, line.length()); - if (addnl) - write(m_Fd, "\n", 1); -} - -void MyPtyProcess::unreadLineFrom(TQCString inbuf, TQCString line, bool addnl) -{ - if (addnl) - line += '\n'; - if (!line.isEmpty()) - inbuf.prepend(line); -} - - -/* - * Fork and execute the command. This returns in the parent. - */ - -int MyPtyProcess::exec(TQCString command, QCStringList args) -{ - kdDebug(PTYPROC) << "MyPtyProcess::exec(): " << command << endl;// << ", args = " << args << endl; - - if (init() < 0) - return -1; - - // Open the pty slave before forking. See SetupTTY() - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(PTYPROC) << k_lineinfo << "Could not open slave pty.\n"; - return -1; - } - - // Also create a socket pair to connect to standard in/out. - // This will allow use to bypass the terminal. - int inout[2]; - int err[2]; - int ok = 1; - ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, inout) >= 0; - ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err ) >= 0; - if( !ok ) { - kdDebug(PTYPROC) << "Could not create socket" << endl; - return -1; - } - m_stdinout = inout[0]; - m_err = err[0]; - - if ((m_Pid = fork()) == -1) - { - kdError(PTYPROC) << k_lineinfo << "fork(): " << perror << "\n"; - return -1; - } - - // Parent - if (m_Pid) - { - close(slave); - close(inout[1]); - close(err[1]); - return 0; - } - - // Child - - ok = 1; - ok &= dup2(inout[1], STDIN_FILENO) >= 0; - ok &= dup2(inout[1], STDOUT_FILENO) >= 0; - ok &= dup2(err[1], STDERR_FILENO) >= 0; - - if( !ok ) - { - kdError(PTYPROC) << "dup of socket descriptor failed" << endl; - _exit(1); - } - - close(inout[1]); - close(inout[0]); - close(err[1]); - close(err[0]); - - if (SetupTTY(slave) < 0) - _exit(1); - - // From now on, terminal output goes through the tty. - TQCString path; - if (command.contains('/')) - path = command; - else - { - TQString file = TDEStandardDirs::findExe(command); - if (file.isEmpty()) - { - kdError(PTYPROC) << k_lineinfo << command << " not found\n"; - _exit(1); - } - path = TQFile::encodeName(file); - } - - int i; - const char * argp[32]; - argp[0] = path; - QCStringList::Iterator it; - for (i=1, it=args.begin(); it!=args.end() && i<31; it++) { - argp[i++] = *it; - kdDebug(PTYPROC) << *it << endl; - } - argp[i] = 0L; - execv(path, (char * const *)argp); - kdError(PTYPROC) << k_lineinfo << "execv(\"" << path << "\"): " << perror << "\n"; - _exit(1); - return -1; // Shut up compiler. Never reached. -} - -/* - * Wait until the terminal is set into no echo mode. At least one su - * (RH6 w/ Linux-PAM patches) sets noecho mode AFTER writing the Password: - * prompt, using TCSAFLUSH. This flushes the terminal I/O queues, possibly - * taking the password with it. So we wait until no echo mode is set - * before writing the password. - * Note that this is done on the slave fd. While Linux allows tcgetattr() on - * the master side, Solaris doesn't. - */ - -int MyPtyProcess::WaitSlave() -{ - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(PTYPROC) << k_lineinfo << "Could not open slave tty.\n"; - return -1; - } - - struct termios tio; - struct timeval tv; - while (1) - { - if (tcgetattr(slave, &tio) < 0) - { - kdError(PTYPROC) << k_lineinfo << "tcgetattr(): " << perror << "\n"; - close(slave); - return -1; - } - if (tio.c_lflag & ECHO) - { - kdDebug(PTYPROC) << k_lineinfo << "Echo mode still on." << endl; - // sleep 1/10 sec - tv.tv_sec = 0; tv.tv_usec = 100000; - select(slave, 0L, 0L, 0L, &tv); - continue; - } - break; - } - close(slave); - return 0; -} - - -int MyPtyProcess::enableLocalEcho(bool enable) -{ - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(PTYPROC) << k_lineinfo << "Could not open slave tty.\n"; - return -1; - } - struct termios tio; - if (tcgetattr(slave, &tio) < 0) - { - kdError(PTYPROC) << k_lineinfo << "tcgetattr(): " << perror << "\n"; - close(slave); return -1; - } - if (enable) - tio.c_lflag |= ECHO; - else - tio.c_lflag &= ~ECHO; - if (tcsetattr(slave, TCSANOW, &tio) < 0) - { - kdError(PTYPROC) << k_lineinfo << "tcsetattr(): " << perror << "\n"; - close(slave); return -1; - } - close(slave); - return 0; -} - - -/* - * Copy output to stdout until the child process exists, or a line of output - * matches `m_Exit'. - * We have to use waitpid() to test for exit. Merely waiting for EOF on the - * pty does not work, because the target process may have children still - * attached to the terminal. - */ - -int MyPtyProcess::waitForChild() -{ - int ret, state, retval = 1; - struct timeval tv; - - fd_set fds; - FD_ZERO(&fds); - - while (1) - { - tv.tv_sec = 1; tv.tv_usec = 0; - FD_SET(m_Fd, &fds); - ret = select(m_Fd+1, &fds, 0L, 0L, &tv); - if (ret == -1) - { - if (errno == EINTR) continue; - else - { - kdError(PTYPROC) << k_lineinfo << "select(): " << perror << "\n"; - return -1; - } - } - - if (ret) - { - TQCString line = readLine(false); - while (!line.isNull()) - { - if (!m_Exit.isEmpty() && !tqstrnicmp(line, m_Exit, m_Exit.length())) - kill(m_Pid, SIGTERM); - if (m_bTerminal) - { - fputs(line, stdout); - fputc('\n', stdout); - } - line = readLine(false); - } - } - - // Check if the process is still alive - ret = waitpid(m_Pid, &state, WNOHANG); - if (ret < 0) - { - if (errno == ECHILD) - retval = 0; - else - kdError(PTYPROC) << k_lineinfo << "waitpid(): " << perror << "\n"; - break; - } - if (ret == m_Pid) - { - if (WIFEXITED(state)) - retval = WEXITSTATUS(state); - break; - } - } - - return -retval; -} - -/* - * SetupTTY: Creates a new session. The filedescriptor "fd" should be - * connected to the tty. It is closed after the tty is reopened to make it - * our controlling terminal. This way the tty is always opened at least once - * so we'll never get EIO when reading from it. - */ - -int MyPtyProcess::SetupTTY(int fd) -{ - // Reset signal handlers - for (int sig = 1; sig < NSIG; sig++) - signal(sig, SIG_DFL); - signal(SIGHUP, SIG_IGN); - - // Close all file handles -// struct rlimit rlp; -// getrlimit(RLIMIT_NOFILE, &rlp); -// for (int i = 0; i < (int)rlp.rlim_cur; i++) -// if (i != fd) close(i); - - // Create a new session. - setsid(); - - // Open slave. This will make it our controlling terminal - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(PTYPROC) << k_lineinfo << "Could not open slave side: " << perror << "\n"; - return -1; - } - close(fd); - -#if defined(__SVR4) && defined(sun) - - // Solaris STREAMS environment. - // Push these modules to make the stream look like a terminal. - ioctl(slave, I_PUSH, "ptem"); - ioctl(slave, I_PUSH, "ldterm"); - -#endif - - // Connect stdin, stdout and stderr -// dup2(slave, 0); dup2(slave, 1); dup2(slave, 2); -// if (slave > 2) -// close(slave); - - // Disable OPOST processing. Otherwise, '\n' are (on Linux at least) - // translated to '\r\n'. - struct termios tio; - if (tcgetattr(slave, &tio) < 0) - { - kdError(PTYPROC) << k_lineinfo << "tcgetattr(): " << perror << "\n"; - return -1; - } - tio.c_oflag &= ~OPOST; - if (tcsetattr(slave, TCSANOW, &tio) < 0) - { - kdError(PTYPROC) << k_lineinfo << "tcsetattr(): " << perror << "\n"; - return -1; - } - - return 0; -} diff --git a/tdeioslave/sftp/process.h b/tdeioslave/sftp/process.h deleted file mode 100644 index 215c51ea7..000000000 --- a/tdeioslave/sftp/process.h +++ /dev/null @@ -1,148 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> - * - * This is free software; you can use this library under the GNU Library - * General Public License, version 2. See the file "COPYING.LIB" for the - * exact licensing terms. - */ - -#ifndef __Process_h_Included__ -#define __Process_h_Included__ - -#include <tqcstring.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqvaluelist.h> - -#define PTYPROC 7120 - -class PTY; -typedef TQValueList<TQCString> QCStringList; - -/** - * Synchronous communication with tty programs. - * - * PtyProcess provides synchronous communication with tty based programs. - * The communications channel used is a pseudo tty (as opposed to a pipe) - * This means that programs which require a terminal will work. - */ - -class MyPtyProcess -{ -public: - MyPtyProcess(); - virtual ~MyPtyProcess(); - - /** - * Fork off and execute a command. The command's standard in and output - * are connected to the pseudo tty. They are accessible with @ref #readLine - * and @ref #writeLine. - * @param command The command to execute. - * @param args The arguments to the command. - */ - int exec(TQCString command, QCStringList args); - - /** - * Read a line from the program's standard out. Depending on the @em block - * parameter, this call blocks until a single, full line is read. - * @param block Block until a full line is read? - * @return The output string. - */ - TQCString readLine(bool block = true) - { return readLineFrom(m_Fd, m_ptyBuf, block); } - - TQCString readLineFromPty(bool block = true) - { return readLineFrom(m_Fd, m_ptyBuf, block); } - - TQCString readLineFromStdout(bool block = true) - { return readLineFrom(m_stdinout, m_stdoutBuf, block); } - - TQCString readLineFromStderr(bool block = true) - { return readLineFrom(m_err, m_stderrBuf, block); } - - /** - * Write a line of text to the program's standard in. - * @param line The text to write. - * @param addNewline Adds a '\n' to the line. - */ - void writeLine(TQCString line, bool addNewline=true); - - /** - * Put back a line of input. - * @param line The line to put back. - * @param addNewline Adds a '\n' to the line. - */ - - void unreadLine(TQCString line, bool addNewline = true) - { unreadLineFrom(m_ptyBuf, line, addNewline); } - - void unreadLineFromPty(TQCString line, bool addNewline = true) - { unreadLineFrom(m_ptyBuf, line, addNewline); } - - void unreadLineFromStderr(TQCString line, bool addNewline = true) - { unreadLineFrom(m_stderrBuf, line, addNewline); } - - void unreadLineFromStdout(TQCString line, bool addNewline = true) - { unreadLineFrom(m_stdoutBuf, line, addNewline); } - - /** - * Set exit string. If a line of program output matches this, - * @ref #waitForChild() will terminate the program and return. - */ - void setExitString(TQCString exit) { m_Exit = exit; } - - /** - * Wait for the child to exit. See also @ref #setExitString. - */ - int waitForChild(); - - /** - * Wait until the pty has cleared the ECHO flag. This is useful - * when programs write a password prompt before they disable ECHO. - * Disabling it might flush any input that was written. - */ - int WaitSlave(); - - /** Enables/disables local echo on the pseudo tty. */ - int enableLocalEcho(bool enable=true); - - /** Enable/disable terminal output. Relevant only to some subclasses. */ - void setTerminal(bool terminal) { m_bTerminal = terminal; } - - /** Overwritte the password as soon as it is used. Relevant only to - * some subclasses. */ - void setErase(bool erase) { m_bErase = erase; } - - /** Return the filedescriptor of the process. */ - int fd() {return m_Fd;} - - /** Return the pid of the process. */ - int pid() {return m_Pid;} - - int stdioFd() {return m_stdinout;} - - int stderrFd() {return m_err;} - -protected: - bool m_bErase, m_bTerminal; - int m_Pid, m_Fd, m_stdinout, m_err; - TQCString m_Command, m_Exit; - -private: - int init(); - int SetupTTY(int fd); - - PTY *m_pPTY; - TQCString m_TTY; - TQCString m_ptyBuf, m_stderrBuf, m_stdoutBuf; - - TQCString readLineFrom(int fd, TQCString& inbuf, bool block); - void unreadLineFrom(TQCString inbuf, TQCString line, bool addnl); - class PtyProcessPrivate; - PtyProcessPrivate *d; -}; - -#endif diff --git a/tdeioslave/sftp/sftp.h b/tdeioslave/sftp/sftp.h deleted file mode 100644 index 95518130d..000000000 --- a/tdeioslave/sftp/sftp.h +++ /dev/null @@ -1,91 +0,0 @@ -/* $OpenBSD: sftp.h,v 1.3 2001/03/07 10:11:23 djm Exp $ */ - -/* - * Copyright (c) 2001 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * draft-ietf-secsh-filexfer-01.txt - */ - -/* version */ -#define SSH2_FILEXFER_VERSION 3 - -/* client to server */ -#define SSH2_FXP_INIT 1 -#define SSH2_FXP_OPEN 3 -#define SSH2_FXP_CLOSE 4 -#define SSH2_FXP_READ 5 -#define SSH2_FXP_WRITE 6 -#define SSH2_FXP_LSTAT 7 -#define SSH2_FXP_FSTAT 8 -#define SSH2_FXP_SETSTAT 9 -#define SSH2_FXP_FSETSTAT 10 -#define SSH2_FXP_OPENDIR 11 -#define SSH2_FXP_READDIR 12 -#define SSH2_FXP_REMOVE 13 -#define SSH2_FXP_MKDIR 14 -#define SSH2_FXP_RMDIR 15 -#define SSH2_FXP_REALPATH 16 -#define SSH2_FXP_STAT 17 -#define SSH2_FXP_RENAME 18 -#define SSH2_FXP_READLINK 19 -#define SSH2_FXP_SYMLINK 20 - -/* server to client */ -#define SSH2_FXP_VERSION 2 -#define SSH2_FXP_STATUS 101 -#define SSH2_FXP_HANDLE 102 -#define SSH2_FXP_DATA 103 -#define SSH2_FXP_NAME 104 -#define SSH2_FXP_ATTRS 105 - -#define SSH2_FXP_EXTENDED 200 -#define SSH2_FXP_EXTENDED_REPLY 201 - -/* attributes */ -#define SSH2_FILEXFER_ATTR_SIZE 0x00000001 -#define SSH2_FILEXFER_ATTR_UIDGID 0x00000002 -#define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004 -#define SSH2_FILEXFER_ATTR_ACMODTIME 0x00000008 -#define SSH2_FILEXFER_ATTR_EXTENDED 0x80000000 - -/* portable open modes */ -#define SSH2_FXF_READ 0x00000001 -#define SSH2_FXF_WRITE 0x00000002 -#define SSH2_FXF_APPEND 0x00000004 -#define SSH2_FXF_CREAT 0x00000008 -#define SSH2_FXF_TRUNC 0x00000010 -#define SSH2_FXF_EXCL 0x00000020 - -/* status messages */ -#define SSH2_FX_OK 0 -#define SSH2_FX_EOF 1 -#define SSH2_FX_NO_SUCH_FILE 2 -#define SSH2_FX_PERMISSION_DENIED 3 -#define SSH2_FX_FAILURE 4 -#define SSH2_FX_BAD_MESSAGE 5 -#define SSH2_FX_NO_CONNECTION 6 -#define SSH2_FX_CONNECTION_LOST 7 -#define SSH2_FX_OP_UNSUPPORTED 8 -#define SSH2_FX_MAX 8 diff --git a/tdeioslave/sftp/sftp.protocol b/tdeioslave/sftp/sftp.protocol index 33e66867a..931ee7890 100644 --- a/tdeioslave/sftp/sftp.protocol +++ b/tdeioslave/sftp/sftp.protocol @@ -2,7 +2,7 @@ exec=tdeio_sftp protocol=sftp input=none -listing=Name,Type,Size,Date,Access,Owner,Group,Link +listing=Name,Type,Size,Date,Access,Owner,Group,Link,MimeType output=filesystem copyToFile=true copyFromFile=true diff --git a/tdeioslave/sftp/sftpfileattr.cpp b/tdeioslave/sftp/sftpfileattr.cpp deleted file mode 100644 index 4c25909d9..000000000 --- a/tdeioslave/sftp/sftpfileattr.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/*************************************************************************** - sftpfileattr.cpp - description - ------------------- - begin : Sat Jun 30 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@iastate.edu - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "sftpfileattr.h" - -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <tqstring.h> -#include <tqdatastream.h> - -#include <tdeio/global.h> -#include <kremoteencoding.h> - -using namespace TDEIO; - -sftpFileAttr::sftpFileAttr(){ - clear(); - mDirAttrs = false; -} - -sftpFileAttr::sftpFileAttr(KRemoteEncoding* encoding){ - clear(); - mDirAttrs = false; - mEncoding = encoding; -} - - -/** Constructor to initialize the file attributes on declaration. */ -sftpFileAttr::sftpFileAttr(TQ_ULLONG size, uid_t uid, gid_t gid, - mode_t permissions, time_t atime, - time_t mtime, TQ_UINT32 extendedCount) { - clear(); - mDirAttrs = false; - mSize = size; - mUid = uid; - mGid = gid; - mAtime = atime; - mMtime = mtime; - mPermissions = permissions; - mExtendedCount = extendedCount; -} - -sftpFileAttr::~sftpFileAttr(){ -} - -/** Returns a UDSEntry describing the file. -The UDSEntry is generated from the sftp file attributes. */ -UDSEntry sftpFileAttr::entry() { - UDSEntry entry; - UDSAtom atom; - - atom.m_uds = UDS_NAME; - atom.m_str = mFilename; - entry.append(atom); - - if( mFlags & SSH2_FILEXFER_ATTR_SIZE ) { - atom.m_uds = UDS_SIZE; - atom.m_long = mSize; - entry.append(atom); - } - - if( mFlags & SSH2_FILEXFER_ATTR_ACMODTIME ) { - atom.m_uds = UDS_ACCESS_TIME; - atom.m_long = mAtime; - entry.append(atom); - - atom.m_uds = UDS_MODIFICATION_TIME; - atom.m_long = mMtime; - entry.append(atom); - } - - if( mFlags & SSH2_FILEXFER_ATTR_UIDGID ) { - if( mUserName.isEmpty() || mGroupName.isEmpty() ) - getUserGroupNames(); - - atom.m_uds = UDS_USER; - atom.m_str = mUserName; - entry.append(atom); - - atom.m_uds = UDS_GROUP; - atom.m_str = mGroupName; - entry.append(atom); - } - - if( mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS ) { - atom.m_uds = UDS_ACCESS; - atom.m_long = mPermissions; - entry.append(atom); - - mode_t type = fileType(); - - // Set the type if we know what it is - if( type != 0 ) { - atom.m_uds = UDS_FILE_TYPE; - atom.m_long = (mLinkType ? mLinkType:type); - entry.append(atom); - } - - if( S_ISLNK(type) ) { - atom.m_uds = UDS_LINK_DEST; - atom.m_str = mLinkDestination; - entry.append(atom); - } - } - - return entry; -} - -/** Use to output the file attributes to a sftp packet */ -TQDataStream& operator<< (TQDataStream& s, const sftpFileAttr& fa) { - s << (TQ_UINT32)fa.mFlags; - - if( fa.mFlags & SSH2_FILEXFER_ATTR_SIZE ) - { s << (TQ_ULLONG)fa.mSize; } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_UIDGID ) - { s << (TQ_UINT32)fa.mUid << (TQ_UINT32)fa.mGid; } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS ) - { s << (TQ_UINT32)fa.mPermissions; } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_ACMODTIME ) - { s << (TQ_UINT32)fa.mAtime << (TQ_UINT32)fa.mMtime; } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_EXTENDED ) { - s << (TQ_UINT32)fa.mExtendedCount; - // XXX: Write extensions to data stream here - // s.writeBytes(extendedtype).writeBytes(extendeddata); - } - return s; -} - - -/** Use to read a file attribute from a sftp packet */ -TQDataStream& operator>> (TQDataStream& s, sftpFileAttr& fa) { - - // XXX Add some error checking in here in case - // we get a bad sftp packet. - - fa.clear(); - - if( fa.mDirAttrs ) { - TQCString fn; - s >> fn; - fn.truncate( fn.size() ); - - fa.mFilename = fa.mEncoding->decode( fn ); - - s >> fa.mLongname; - fa.mLongname.truncate( fa.mLongname.size() ); - //kdDebug() << ">>: ftpfileattr long filename (" << fa.mLongname.size() << ")= " << fa.mLongname << endl; - } - - s >> fa.mFlags; // get flags - - if( fa.mFlags & SSH2_FILEXFER_ATTR_SIZE ) { - TQ_ULLONG fileSize; - s >> fileSize; - fa.setFileSize(fileSize); - } - - TQ_UINT32 x; - - if( fa.mFlags & SSH2_FILEXFER_ATTR_UIDGID ) { - s >> x; fa.setUid(x); - s >> x; fa.setGid(x); - } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS ) { - s >> x; fa.setPermissions(x); - } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_ACMODTIME ) { - s >> x; fa.setAtime(x); - s >> x; fa.setMtime(x); - } - - if( fa.mFlags & SSH2_FILEXFER_ATTR_EXTENDED ) { - s >> x; fa.setExtendedCount(x); - // XXX: Read in extensions from data stream here - // s.readBytes(extendedtype).readBytes(extendeddata); - } - - fa.getUserGroupNames(); - return s; -} -/** Parse longname for the owner and group names. */ -void sftpFileAttr::getUserGroupNames(){ - // Get the name of the owner and group of the file from longname. - TQString user, group; - if( mLongname.isEmpty() ) { - // do not have the user name so use the user id instead - user.setNum(mUid); - group.setNum(mGid); - } - else { - int field = 0; - int i = 0; - int l = mLongname.length(); - - TQString longName = mEncoding->decode( mLongname ); - - kdDebug(7120) << "Decoded: " << longName << endl; - - // Find the beginning of the third field which contains the user name. - while( field != 2 ) { - if( longName[i].isSpace() ) { - field++; i++; - while( i < l && longName[i].isSpace() ) { i++; } - } - else { i++; } - } - // i is the index of the first character of the third field. - while( i < l && !longName[i].isSpace() ) { - user.append(longName[i]); - i++; - } - - // i is the first character of the space between fields 3 and 4 - // user contains the owner's user name - while( i < l && longName[i].isSpace() ) { - i++; - } - - // i is the first character of the fourth field - while( i < l && !longName[i].isSpace() ) { - group.append(longName[i]); - i++; - } - // group contains the name of the group. - } - - mUserName = user; - mGroupName = group; -} - -/** No descriptions */ -kdbgstream& operator<< (kdbgstream& s, sftpFileAttr& a) { - s << "Filename: " << a.mFilename - << ", Uid: " << a.mUid - << ", Gid: " << a.mGid - << ", Username: " << a.mUserName - << ", GroupName: " << a.mGroupName - << ", Permissions: " << a.mPermissions - << ", size: " << a.mSize - << ", atime: " << a.mAtime - << ", mtime: " << a.mMtime - << ", extended cnt: " << a.mExtendedCount; - - if (S_ISLNK(a.mLinkType)) { - s << ", Link Type: " << a.mLinkType; - s << ", Link Destination: " << a.mLinkDestination; - } - - return s; -} - -/** Make sure it builds with NDEBUG */ -kndbgstream& operator<< (kndbgstream& s, sftpFileAttr& ) { - return s; -} - -/** Clear all attributes and flags. */ -void sftpFileAttr::clear(){ - clearAtime(); - clearMtime(); - clearGid(); - clearUid(); - clearFileSize(); - clearPermissions(); - clearExtensions(); - mFilename = TQString::null; - mGroupName = TQString::null; - mUserName = TQString::null; - mLinkDestination = TQString::null; - mFlags = 0; - mLongname = "\0"; - mLinkType = 0; -} - -/** Return the size of the sftp attribute. */ -TQ_UINT32 sftpFileAttr::size() const{ - TQ_UINT32 size = 4; // for the attr flag - if( mFlags & SSH2_FILEXFER_ATTR_SIZE ) - size += 8; - - if( mFlags & SSH2_FILEXFER_ATTR_UIDGID ) - size += 8; - - if( mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS ) - size += 4; - - if( mFlags & SSH2_FILEXFER_ATTR_ACMODTIME ) - size += 8; - - if( mFlags & SSH2_FILEXFER_ATTR_EXTENDED ) { - size += 4; - // add size of extensions - } - return size; -} - -/** Returns the file type as determined from the file permissions */ -mode_t sftpFileAttr::fileType() const{ - mode_t type = 0; - - if( S_ISLNK(mPermissions) ) - type |= S_IFLNK; - - if( S_ISREG(mPermissions) ) - type |= S_IFREG; - else if( S_ISDIR(mPermissions) ) - type |= S_IFDIR; - else if( S_ISCHR(mPermissions) ) - type |= S_IFCHR; - else if( S_ISBLK(mPermissions) ) - type |= S_IFBLK; - else if( S_ISFIFO(mPermissions) ) - type |= S_IFIFO; - else if( S_ISSOCK(mPermissions) ) - type |= S_IFSOCK; - - return type; -} - -void sftpFileAttr::setEncoding( KRemoteEncoding* encoding ) -{ - mEncoding = encoding; -} -// vim:ts=4:sw=4 diff --git a/tdeioslave/sftp/sftpfileattr.h b/tdeioslave/sftp/sftpfileattr.h deleted file mode 100644 index 43b56979d..000000000 --- a/tdeioslave/sftp/sftpfileattr.h +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************** - sftpfileattr.h - description - ------------------- - begin : Sat Jun 30 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@iastate.edu - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef SFTPFILEATTR_H -#define SFTPFILEATTR_H - -#include <sys/types.h> - -#include <tqglobal.h> -#include <tqstring.h> -#include <tqdatastream.h> - -#include <tdeio/global.h> -#include <kdebug.h> - -#include "sftp.h" - -/** - *@author Lucas Fisher - */ - -class KRemoteEncoding; - -class sftpFileAttr { - -private: // Private attributes - /** Name of file. */ - TQString mFilename; - - /** Specifies which fields of the file attribute are available. */ - TQ_UINT32 mFlags; - - /** Size of the file in bytes. Should be 64 bit safe. */ - TQ_ULLONG mSize; - - /** User id of the owner of the file. */ - uid_t mUid; - - /** Group id of the group to which the file belongs. */ - gid_t mGid; - - /** POSIX permissions of the file. */ - mode_t mPermissions; - - /** Last access time of the file in seconds from Jan 1, 1970. */ - time_t mAtime; - - /** Last modification time of file in seconds since Jan. 1, 1970. */ - time_t mMtime; - - /** Number of file attribute extensions. - Not currently implemented */ - TQ_UINT32 mExtendedCount; - - /** Longname of the file as found in a SSH_FXP_NAME sftp packet. - These contents are parse to return the file's owner name and - gr oup name. */ - TQCString mLongname; - - TQString mUserName; - TQString mGroupName; - - /** If file is a link, contains the destination of the link */ - TQString mLinkDestination; - - /** If resource is a link, contains the type the link,e.g. file,dir... */ - mode_t mLinkType; - - /** Whether >> operator should read filename and longname from the stream. */ - bool mDirAttrs; - - /** Holds the encoding of the remote host */ - KRemoteEncoding* mEncoding; - -public: - sftpFileAttr(); - - sftpFileAttr(KRemoteEncoding* encoding); - - ~sftpFileAttr(); - - /** Constructor to initialize the file attributes on declaration. */ - sftpFileAttr(TQ_ULLONG size_, uid_t uid_, gid_t gid_, mode_t permissions_, - time_t atime_, time_t mtime_, TQ_UINT32 extendedCount_ = 0); - - /** Return the size of the sftp attribute not including filename or longname*/ - TQ_UINT32 size() const; - - /** Clear all attributes and flags. */ - void clear(); - - /** Set the size of the file. */ - void setFileSize(TQ_ULLONG s) - { mSize = s; mFlags |= SSH2_FILEXFER_ATTR_SIZE; } - - /** The size file attribute will not be included in the UDSEntry - or when the file attribute is written to the sftp packet. */ - void clearFileSize() - { mSize = 0; mFlags &= ~SSH2_FILEXFER_ATTR_SIZE; } - - /** Returns the size of the file. */ - TQ_ULLONG fileSize() const { return mSize; } - - /** Sets the POSIX permissions of the file. */ - void setPermissions(mode_t p) - { mPermissions = p; mFlags |= SSH2_FILEXFER_ATTR_PERMISSIONS; } - - /** The permissions file attribute will not be included in the UDSEntry - or when the file attribute is written to the sftp packet. */ - void clearPermissions() - { mPermissions = 0; mFlags &= ~SSH2_FILEXFER_ATTR_PERMISSIONS; } - - /** Returns the POSIX permissons of the file. */ - mode_t permissions() const { return mPermissions; } - - /** Sets the group id of the file. */ - void setGid(gid_t id) - { mGid = id; mFlags |= SSH2_FILEXFER_ATTR_UIDGID; } - - /** Neither the gid or uid file attributes will not be included in the UDSEntry - or when the file attribute is written to the sftp packet. This is - equivalent to clearUid() */ - void clearGid() - { mGid = 0; mFlags &= SSH2_FILEXFER_ATTR_UIDGID; } - - /** Returns the group id of the file. */ - gid_t gid() const { return mGid; } - - /** Sets the uid of the file. */ - void setUid(uid_t id) - { mUid = id; mFlags |= SSH2_FILEXFER_ATTR_UIDGID; } - - /** Neither the gid or uid file attributes will not be included in the UDSEntry - or when the file attribute is written to the sftp packet. This is - equivalent to clearGid() */ - void clearUid() - { mUid = 0; mFlags &= SSH2_FILEXFER_ATTR_UIDGID; } - - /** Returns the user id of the file. */ - gid_t uid() const { return mUid; } - - /** Set the modificatoin time of the file in seconds since Jan. 1, 1970. */ - void setMtime(time_t t) - { mMtime = t; mFlags |= SSH2_FILEXFER_ATTR_ACMODTIME; } - - /** Neither the mtime or atime file attributes will not be included in the UDSEntry - or when the file attribute is written to the sftp packet. This is - equivalent to clearAtime() */ - void clearMtime() - { mMtime = 0; mFlags &= SSH2_FILEXFER_ATTR_ACMODTIME; } - - /** Returns the modification time of the file in seconds since Jan. 1, 1970. */ - time_t mtime() const { return mMtime; } - - /** Sets the access time of the file in seconds since Jan. 1, 1970. */ - void setAtime(time_t t) - { mAtime = t; mFlags |= SSH2_FILEXFER_ATTR_ACMODTIME; } - - /** Neither the atime or mtime file attributes will not be included in the UDSEntry - or when the file attribute is written to the sftp packet. This is - equivalent to clearMtime() */ - void clearAtime() - { mAtime = 0; mFlags &= SSH2_FILEXFER_ATTR_ACMODTIME; } - - /** Returns the last access time of the file in seconds since Jan. 1, 1970. */ - time_t atime() const { return mAtime; } - - /** Sets the number of file attribute extensions. */ - void setExtendedCount(unsigned int c) - { mExtendedCount = c; mFlags |= SSH2_FILEXFER_ATTR_EXTENDED; } - - /** No extensions will be included when the file attribute is written - to a sftp packet. */ - void clearExtensions() - { mExtendedCount = 0; mFlags &= ~SSH2_FILEXFER_ATTR_EXTENDED; } - - /** Returns the number of file attribute extentsions. */ - unsigned int extendedCount() const { return mExtendedCount; } - - /** Returns the flags for the sftp file attributes. */ - unsigned int flags() const { return mFlags; } - - /** Sets file's longname. See sftpFileAttr::longname. */ - void setLongname(TQString l) { mLongname = l.latin1(); } - - /** Returns a string describing the file attributes. The format is specific - to the implementation of the sftp server. In most cases (ie OpenSSH) - this is similar to the long output of 'ls'. */ - TQString longname() const { return mLongname; } - - void setLinkDestination(const TQString& target) - { mLinkDestination = target; } - - TQString linkDestination() - { return mLinkDestination; } - - /** Sets the actual type a symbolic link points to. */ - void setLinkType (mode_t type) { mLinkType = type; } - - mode_t linkType() const { return mLinkType; } - - /** No descriptions */ - void setFilename(const TQString& fn) - { mFilename = fn; } - - TQString filename() const - { return mFilename; } - - /** Returns a UDSEntry describing the file. - The UDSEntry is generated from the sftp file attributes. */ - TDEIO::UDSEntry entry(); - - /** Use to output the file attributes to a sftp packet - This will only write the sftp ATTR structure to the stream. - It will never write the filename and longname because the client - never sends those to the server. */ - friend TQDataStream& operator<< (TQDataStream&, const sftpFileAttr&); - - /** Use to read a file attribute from a sftp packet. - Read this carefully! If the DirAttrs flag is true, this will - read the filename, longname, and file attributes from the stream. - This is for use with listing directories. - If the DirAttrs flag is false, this will only read file attributes - from the stream. - BY DEFAULT, A NEW INSTANCE HAS DirAttrs == false */ - friend TQDataStream& operator>> (TQDataStream&, sftpFileAttr&); - - /** Parse longname for the owner and group names. */ - void getUserGroupNames(); - - /** Sets the DirAttrs flag. This flag affects how the >> operator works on data streams. */ - void setDirAttrsFlag(bool flag){ mDirAttrs = flag; } - - /** Gets the DirAttrs flag. */ - bool getDirAttrsFlag() const { return mDirAttrs; } - - friend kdbgstream& operator<< (kdbgstream& s, sftpFileAttr& a); - friend kndbgstream& operator<< (kndbgstream& s, sftpFileAttr& a); - - /** Returns the file type as determined from the file permissions */ - mode_t fileType() const; - - /** Set the encoding of the remote file system */ - void setEncoding( KRemoteEncoding* encoding ); -}; - -#endif diff --git a/tdeioslave/sftp/tdeio_sftp.cpp b/tdeioslave/sftp/tdeio_sftp.cpp index eab0eae42..0abcd6238 100644 --- a/tdeioslave/sftp/tdeio_sftp.cpp +++ b/tdeioslave/sftp/tdeio_sftp.cpp @@ -1,62 +1,58 @@ -/*************************************************************************** - sftp.cpp - description - ------------------- - begin : Fri Jun 29 23:45:40 CDT 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - /* -DEBUGGING -We are pretty much left with kdDebug messages for debugging. We can't use a gdb -as described in the ioslave DEBUG.howto because tdeinit has to run in a terminal. -Ssh will detect this terminal and ask for a password there, but will just get garbage. -So we can't connect. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif + * Copyright (c) 2001 Lucas Fisher <ljfisher@purdue.edu> + * Copyright (c) 2009 Andreas Schneider <mail@cynapses.org> + * Copyright (c) 2020 Martin Sandsmark <martin@sandsmark.ninja> + * KDE2 port + * Copyright (c) 2022 Mavridis Philippe <mavridisf@gmail.com> + * Trinity port + * + * Portions Copyright (c) 2020-2021 Harald Sitter <sitter@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License (LGPL) as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later + * version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "tdeio_sftp.h" #include <fcntl.h> -#include <tqcstring.h> -#include <tqstring.h> -#include <tqobject.h> -#include <tqstrlist.h> +#include <tqapplication.h> #include <tqfile.h> -#include <tqbuffer.h> +#include <tqdir.h> + +#include <numeric> +#include <functional> +#include <vector> #include <stdlib.h> #include <unistd.h> -#include <signal.h> #include <errno.h> -#include <ctype.h> #include <time.h> -#include <netdb.h> #include <string.h> -#include <netinet/in.h> #include <arpa/inet.h> +#include <netinet/in.h> + #include <sys/time.h> #include <sys/stat.h> #include <sys/types.h> -#include <sys/wait.h> #include <tdeapplication.h> -#include <kuser.h> #include <kdebug.h> #include <tdemessagebox.h> -#include <kinstance.h> #include <tdeglobal.h> #include <kstandarddirs.h> #include <tdelocale.h> @@ -64,15 +60,14 @@ So we can't connect. #include <tdeio/ioslave_defaults.h> #include <kmimetype.h> #include <kmimemagic.h> -#include <klargefile.h> -#include <kremoteencoding.h> +#include <signal.h> -#include "sftp.h" -#include "tdeio_sftp.h" -#include "atomicio.h" -#include "sftpfileattr.h" -#include "ksshprocess.h" +#include <libssh/libssh.h> +#include <libssh/sftp.h> +#include <libssh/callbacks.h> +#define TDEIO_SFTP_SPECIAL_TIMEOUT 30 +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) using namespace TDEIO; extern "C" @@ -87,8 +82,13 @@ extern "C" kdDebug(TDEIO_SFTP_DB) << "Usage: tdeio_sftp protocol domain-socket1 domain-socket2" << endl; exit(-1); } - sftpProtocol slave(argv[2], argv[3]); + + if (getenv("DEBUG_TDEIO_SFTP")) { + // Give us a coredump in the journal + signal(6, SIG_DFL); + } + slave.dispatchLoop(); kdDebug(TDEIO_SFTP_DB) << "*** tdeio_sftp Done" << endl; @@ -96,2187 +96,2134 @@ extern "C" } } +// Some helper functions/classes +namespace { -/* - * This helper handles some special issues (blocking and interrupted - * system call) when writing to a file handle. - * - * @return 0 on success or an error code on failure (ERR_COULD_NOT_WRITE, - * ERR_DISK_FULL, ERR_CONNECTION_BROKEN). - */ -static int writeToFile (int fd, const char *buf, size_t len) -{ - while (len > 0) - { - ssize_t written = ::write(fd, buf, len); - if (written >= 0) - { - buf += written; - len -= written; - continue; - } - - switch(errno) - { - case EINTR: - continue; - case EPIPE: - return ERR_CONNECTION_BROKEN; - case ENOSPC: - return ERR_DISK_FULL; - default: - return ERR_COULD_NOT_WRITE; - } +// A quick and dirty scope guard implementation +class ExitGuard { +public: + template<class Callable> + ExitGuard(Callable && undo_func) : f(std::forward<Callable>(undo_func)) {} + ExitGuard(ExitGuard && other) : f(std::move(other.f)) { + other.f = nullptr; } - return 0; -} - -sftpProtocol::sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : SlaveBase("tdeio_sftp", pool_socket, app_socket), - mConnected(false), mPort(-1), mMsgId(0) { - kdDebug(TDEIO_SFTP_DB) << "sftpProtocol(): pid = " << getpid() << endl; -} - -sftpProtocol::~sftpProtocol() { - kdDebug(TDEIO_SFTP_DB) << "~sftpProtocol(): pid = " << getpid() << endl; - closeConnection(); -} + ~ExitGuard() { + run(); + } -/** - * Type is a sftp packet type found in .sftp.h'. - * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. - * - * Returns true if the type is supported by the sftp protocol - * version negotiated by the client and server (sftpVersion). - */ -bool sftpProtocol::isSupportedOperation(int type) { - switch (type) { - case SSH2_FXP_VERSION: - case SSH2_FXP_STATUS: - case SSH2_FXP_HANDLE: - case SSH2_FXP_DATA: - case SSH2_FXP_NAME: - case SSH2_FXP_ATTRS: - case SSH2_FXP_INIT: - case SSH2_FXP_OPEN: - case SSH2_FXP_CLOSE: - case SSH2_FXP_READ: - case SSH2_FXP_WRITE: - case SSH2_FXP_LSTAT: - case SSH2_FXP_FSTAT: - case SSH2_FXP_SETSTAT: - case SSH2_FXP_FSETSTAT: - case SSH2_FXP_OPENDIR: - case SSH2_FXP_READDIR: - case SSH2_FXP_REMOVE: - case SSH2_FXP_MKDIR: - case SSH2_FXP_RMDIR: - case SSH2_FXP_REALPATH: - case SSH2_FXP_STAT: - return true; - case SSH2_FXP_RENAME: - return sftpVersion >= 2 ? true : false; - case SSH2_FXP_EXTENDED: - case SSH2_FXP_EXTENDED_REPLY: - case SSH2_FXP_READLINK: - case SSH2_FXP_SYMLINK: - return sftpVersion >= 3 ? true : false; - default: - kdDebug(TDEIO_SFTP_DB) << "isSupportedOperation(type:" - << type << "): unrecognized operation type" << endl; - break; + void run() noexcept { + if(f) { f(); f = nullptr; } } - return false; -} + void abort() { + f = nullptr; + } -void sftpProtocol::copy(const KURL &src, const KURL &dest, int permissions, bool overwrite) -{ - kdDebug(TDEIO_SFTP_DB) << "copy(): " << src << " -> " << dest << endl; + ExitGuard(const ExitGuard&) = delete; + void operator= (const ExitGuard&) = delete; - bool srcLocal = src.isLocalFile(); - bool destLocal = dest.isLocalFile(); +private: + std::function<void()> f; +}; - if ( srcLocal && !destLocal ) // Copy file -> sftp - sftpCopyPut(src, dest, permissions, overwrite); - else if ( destLocal && !srcLocal ) // Copy sftp -> file - sftpCopyGet(dest, src, permissions, overwrite); - else - error(ERR_UNSUPPORTED_ACTION, TQString::null); +// A small helper to purge passwords. Paranoiac's note: this is not enough to guarantee the +// complete purge of the password and all its copy from memory (ioslaves are sending the passwords +// via dcop, so it's far beyond calling it "secure" in any way), but it's still better than nothing. +void purgeString(TQString &s) { + s.fill('\0'); + s.setLength(0); + s = TQString::null; } -void sftpProtocol::sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite) -{ - kdDebug(TDEIO_SFTP_DB) << "sftpCopyGet(): " << src << " -> " << dest << endl; - - // Attempt to establish a connection... - openConnection(); - if( !mConnected ) - return; - - KDE_struct_stat buff_orig; - TQCString dest_orig ( TQFile::encodeName(dest.path()) ); - bool origExists = (KDE_lstat( dest_orig.data(), &buff_orig ) != -1); - - if (origExists) - { - if (S_ISDIR(buff_orig.st_mode)) - { - error(ERR_IS_DIRECTORY, dest.prettyURL()); - return; - } - - if (!overwrite) - { - error(ERR_FILE_ALREADY_EXIST, dest.prettyURL()); - return; - } - } - - TDEIO::filesize_t offset = 0; - TQCString dest_part ( dest_orig + ".part" ); - - int fd = -1; - bool partExists = false; - bool markPartial = config()->readBoolEntry("MarkPartial", true); - - if (markPartial) - { - KDE_struct_stat buff_part; - partExists = (KDE_stat( dest_part.data(), &buff_part ) != -1); - - if (partExists && buff_part.st_size > 0 && S_ISREG(buff_part.st_mode)) - { - if (canResume( buff_part.st_size )) - { - offset = buff_part.st_size; - kdDebug(TDEIO_SFTP_DB) << "sftpCopyGet: Resuming @ " << offset << endl; - } - } - - if (offset > 0) - { - fd = KDE_open(dest_part.data(), O_RDWR); - offset = KDE_lseek(fd, 0, SEEK_END); - if (offset == 0) - { - error(ERR_CANNOT_RESUME, dest.prettyURL()); - return; - } - } - else - { - // Set up permissions properly, based on what is done in file io-slave - int openFlags = (O_CREAT | O_TRUNC | O_WRONLY); - int initialMode = (mode == -1) ? 0666 : (mode | S_IWUSR); - fd = KDE_open(dest_part.data(), openFlags, initialMode); - } - } - else - { - // Set up permissions properly, based on what is done in file io-slave - int openFlags = (O_CREAT | O_TRUNC | O_WRONLY); - int initialMode = (mode == -1) ? 0666 : (mode | S_IWUSR); - fd = KDE_open(dest_orig.data(), openFlags, initialMode); - } - - if(fd == -1) - { - kdDebug(TDEIO_SFTP_DB) << "sftpCopyGet: Unable to open (" << fd << ") for writting." << endl; - if (errno == EACCES) - error (ERR_WRITE_ACCESS_DENIED, dest.prettyURL()); - else - error (ERR_CANNOT_OPEN_FOR_WRITING, dest.prettyURL()); - return; - } +// A helper class to cleanup password when it goes out of the scope +class PasswordPurger: public ExitGuard { +public: + PasswordPurger(TQString &pw) : ExitGuard( [&pw](){purgeString(pw);} ) {} +}; - Status info = sftpGet(src, offset, fd); - if ( info.code != 0 ) - { - // Should we keep the partially downloaded file ?? - TDEIO::filesize_t size = config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); - if (info.size < size) - ::remove(dest_part.data()); +} /* namespace */ - error(info.code, info.text); - return; - } +// The callback function for libssh +int auth_callback(const char *prompt, char *buf, size_t len, + int echo, int verify, void *userdata) +{ + if (userdata == NULL) { + return -1; + } - if (::close(fd) != 0) - { - error(ERR_COULD_NOT_WRITE, dest.prettyURL()); - return; - } + sftpProtocol *slave = (sftpProtocol *) userdata; - // - if (markPartial) - { - if (::rename(dest_part.data(), dest_orig.data()) != 0) - { - error (ERR_CANNOT_RENAME_PARTIAL, dest_part); - return; - } - } + if (slave->auth_callback(prompt, buf, len, echo, verify, userdata) < 0) { + return -1; + } - data(TQByteArray()); - kdDebug(TDEIO_SFTP_DB) << "sftpCopyGet(): emit finished()" << endl; - finished(); + return 0; } -sftpProtocol::Status sftpProtocol::sftpGet( const KURL& src, TDEIO::filesize_t offset, int fd ) -{ - int code; - sftpFileAttr attr(remoteEncoding()); - - Status res; - res.code = 0; - res.size = 0; - - kdDebug(TDEIO_SFTP_DB) << "sftpGet(): " << src << endl; +void log_callback(ssh_session session, int priority, const char *message, + void *userdata) { + if (userdata == NULL) { + return; + } - // stat the file first to get its size - if( (code = sftpStat(src, attr)) != SSH2_FX_OK ) { - return doProcessStatus(code, src.prettyURL()); - } + sftpProtocol *slave = (sftpProtocol *) userdata; - // We cannot get file if it is a directory - if( attr.fileType() == S_IFDIR ) { - res.text = src.prettyURL(); - res.code = ERR_IS_DIRECTORY; - return res; - } + slave->log_callback(session, priority, message, userdata); +} - TDEIO::filesize_t fileSize = attr.fileSize(); - TQ_UINT32 pflags = SSH2_FXF_READ; - attr.clear(); +class PublicKeyAuth: public SSHAuthMethod { +public: + unsigned flag() override {return SSH_AUTH_METHOD_PUBLICKEY;}; + int authenticate(sftpProtocol *ioslave) const override { + return ioslave->authenticatePublicKey(); + } + SSHAuthMethod* clone() override {return new PublicKeyAuth; } +}; - TQByteArray handle; - if( (code = sftpOpen(src, pflags, attr, handle)) != SSH2_FX_OK ) { - res.text = src.prettyURL(); - res.code = ERR_CANNOT_OPEN_FOR_READING; - return res; - } +class KeyboardInteractiveAuth: public SSHAuthMethod { +public: + KeyboardInteractiveAuth(bool noPaswordQuery = false): mNoPaswordQuery(noPaswordQuery) {} - // needed for determining mimetype - // note: have to emit mimetype before emitting totalsize. - TQByteArray buff; - TQByteArray mimeBuffer; - - unsigned int oldSize; - bool foundMimetype = false; - - // How big should each data packet be? Definitely not bigger than 64kb or - // you will overflow the 2 byte size variable in a sftp packet. - TQ_UINT32 len = 60*1024; - code = SSH2_FX_OK; - - kdDebug(TDEIO_SFTP_DB) << "sftpGet(): offset = " << offset << endl; - while( code == SSH2_FX_OK ) { - if( (code = sftpRead(handle, offset, len, buff)) == SSH2_FX_OK ) { - offset += buff.size(); - - // save data for mimetype. Pretty much follows what is in the ftp ioslave - if( !foundMimetype ) { - oldSize = mimeBuffer.size(); - mimeBuffer.resize(oldSize + buff.size()); - memcpy(mimeBuffer.data()+oldSize, buff.data(), buff.size()); - - if( mimeBuffer.size() > 1024 || offset == fileSize ) { - // determine mimetype - KMimeMagicResult* result = - KMimeMagic::self()->findBufferFileType(mimeBuffer, src.fileName()); - kdDebug(TDEIO_SFTP_DB) << "sftpGet(): mimetype is " << - result->mimeType() << endl; - mimeType(result->mimeType()); - - // Always send the total size after emitting mime-type... - totalSize(fileSize); - - if (fd == -1) - data(mimeBuffer); - else - { - if ( (res.code=writeToFile(fd, mimeBuffer.data(), mimeBuffer.size())) != 0 ) - return res; - } - - processedSize(mimeBuffer.size()); - mimeBuffer.resize(0); - foundMimetype = true; - } - } - else { - if (fd == -1) - data(buff); - else - { - if ( (res.code= writeToFile(fd, buff.data(), buff.size())) != 0 ) - return res; - } - processedSize(offset); - } - } + unsigned flag() override {return SSH_AUTH_METHOD_INTERACTIVE;}; + int authenticate(sftpProtocol *ioslave) const override { + return ioslave->authenticateKeyboardInteractive(mNoPaswordQuery); + } + SSHAuthMethod* clone() override {return new KeyboardInteractiveAuth(mNoPaswordQuery); } - /* - Check if slave was killed. According to slavebase.h we need to leave - the slave methods as soon as possible if the slave is killed. This - allows the slave to be cleaned up properly. - */ - if( wasKilled() ) { - res.text = i18n("An internal error occurred. Please retry the request again."); - res.code = ERR_UNKNOWN; - return res; - } - } +private: + const bool mNoPaswordQuery; +}; - if( code != SSH2_FX_EOF ) { - res.text = src.prettyURL(); - res.code = ERR_COULD_NOT_READ; // return here or still send empty array to indicate end of read? - } +class PasswordAuth: public SSHAuthMethod { +public: + PasswordAuth(bool noPaswordQuery = false): mNoPaswordQuery(noPaswordQuery) {} - res.size = offset; - sftpClose(handle); - processedSize (offset); - return res; + unsigned flag() override {return SSH_AUTH_METHOD_PASSWORD;}; + int authenticate(sftpProtocol *ioslave) const override { + return ioslave->authenticatePassword(mNoPaswordQuery); + } + SSHAuthMethod* clone() override {return new PasswordAuth(mNoPaswordQuery); } + +private: + const bool mNoPaswordQuery; +}; + +TQString SSHAuthMethod::flagToStr (unsigned m) { + switch (m) { + case SSH_AUTH_METHOD_NONE : return TQString::fromLatin1 ( "none" ); + case SSH_AUTH_METHOD_PASSWORD : return TQString::fromLatin1 ( "password" ); + case SSH_AUTH_METHOD_PUBLICKEY : return TQString::fromLatin1 ( "publickey" ); + case SSH_AUTH_METHOD_HOSTBASED : return TQString::fromLatin1 ( "hostbased" ); + case SSH_AUTH_METHOD_INTERACTIVE : return TQString::fromLatin1 ( "keyboard-interactive" ); + case SSH_AUTH_METHOD_GSSAPI_MIC : return TQString::fromLatin1 ( "gssapi-with-mic" ); + default : return TQString::fromLatin1 ( "unknown" ); + } } -void sftpProtocol::get(const KURL& url) { - kdDebug(TDEIO_SFTP_DB) << "get(): " << url << endl ; - - openConnection(); - if( !mConnected ) - return; +TQStringList SSHAuthMethod::bitsetToStr (unsigned m) { + TQStringList rv; - // Get resume offset - TQ_UINT64 offset = config()->readUnsignedLongNumEntry("resume"); - if( offset > 0 ) { - canResume(); - kdDebug(TDEIO_SFTP_DB) << "get(): canResume(), offset = " << offset << endl; + for (int i=0; m>>i; i++) { + unsigned flag = m & (1 << i); + if (flag) { + rv.append(flagToStr(flag)); } - - Status info = sftpGet(url, offset); - - if (info.code != 0) - { - error(info.code, info.text); - return; - } - - data(TQByteArray()); - kdDebug(TDEIO_SFTP_DB) << "get(): emit finished()" << endl; - finished(); + } + return rv; } -void sftpProtocol::setHost (const TQString& h, int port, const TQString& user, const TQString& pass) +// Public key authentication +int sftpProtocol::auth_callback(const char *prompt, char *buf, size_t len, + int echo, int verify, void *userdata) { - kdDebug(TDEIO_SFTP_DB) << "setHost(): " << user << "@" << h << ":" << port << endl; + // unused variables + (void) echo; + (void) verify; + (void) userdata; + (void) prompt; - if( mHost != h || mPort != port || user != mUsername || mPassword != pass ) - closeConnection(); + Q_ASSERT(len>0); - mHost = h; + kdDebug(TDEIO_SFTP_DB) << "Entering public key authentication callback" << endl; - if( port > 0 ) - mPort = port; - else { - mPort = -1; - } + int rc=0; + bool firstTimeCalled = !mPubKeyAuthData.wasCalled; + mPubKeyAuthData.wasCalled = true; - mUsername = user; - mPassword = pass; + AuthInfo pubKeyInfo = authInfo(); - if (user.isEmpty()) - { - KUser u; - mUsername = u.loginName(); - } -} + pubKeyInfo.keepPassword = false; // don't save passwords for public key, + // that's the task of ssh-agent. + pubKeyInfo.readOnly = true; // We don't want to handle user name change when authing with a key + TQString errMsg; + TQString keyFile; +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 10, 0) + // no way to determine keyfile name on older libssh +#else + char *ssh_key_file = 0; + rc = ssh_userauth_publickey_auto_get_current_identity(mSession, &ssh_key_file); -void sftpProtocol::openConnection() { - - if(mConnected) - return; + if (rc == 0 && ssh_key_file && ssh_key_file[0]) { + keyFile = ssh_key_file; + } + ssh_string_free_char(ssh_key_file); +#endif - kdDebug(TDEIO_SFTP_DB) << "openConnection(): " << mUsername << "@" - << mHost << ":" << mPort << endl; + bool firstTry = !mPubKeyAuthData.attemptedKeys.contains(keyFile); - infoMessage( i18n("Opening SFTP connection to host <b>%1:%2</b>").arg(mHost).arg(mPort)); + if (firstTry) { + SlaveBase::s_seqNr = mPubKeyAuthData.current_seqNr; + } else { + errMsg = i18n("Incorrect or invalid passphrase.").append('\n'); + } - if( mHost.isEmpty() ) { - kdDebug(TDEIO_SFTP_DB) << "openConnection(): Need hostname..." << endl; - error(ERR_UNKNOWN_HOST, i18n("No hostname specified")); - return; - } + // libssh prompt is trash and we know we use this function only for publickey auth, so we'll give + // the user a descent prompt + if (!keyFile.isEmpty()) { + pubKeyInfo.prompt = i18n("Please enter the passphrase for next public key:\n%1").arg(keyFile); + } else { // Generally shouldn't happend but on older libssh + pubKeyInfo.prompt = i18n("Please enter the passphrase for your public key."); + } - //////////////////////////////////////////////////////////////////////////// - // Setup AuthInfo for use with password caching and the - // password dialog box. - AuthInfo info; - info.url.setProtocol("sftp"); - info.url.setHost(mHost); - info.url.setPort(mPort); - info.url.setUser(mUsername); - info.caption = i18n("SFTP Login"); - info.comment = "sftp://" + mHost + ":" + TQString::number(mPort); - info.commentLabel = i18n("site:"); - info.username = mUsername; - info.keepPassword = true; - - /////////////////////////////////////////////////////////////////////////// - // Check for cached authentication info if a username AND password were - // not specified in setHost(). - if( mUsername.isEmpty() && mPassword.isEmpty() ) { - kdDebug(TDEIO_SFTP_DB) << "openConnection(): checking cache " - << "info.username = " << info.username - << ", info.url = " << info.url.prettyURL() << endl; - - if( checkCachedAuthentication(info) ) { - mUsername = info.username; - mPassword = info.password; - } - } + // We don't want to clobber with normal passwords in kpasswdserver's cache + pubKeyInfo.realmValue = "keyfile passphrase:" + keyFile; - /////////////////////////////////////////////////////////////////////////// - // Now setup our ssh options. If we found a cached username - // and password we set the SSH_PASSWORD and SSH_USERNAME - // options right away. Otherwise we wait. The other options are - // necessary for running sftp over ssh. - KSshProcess::SshOpt opt; // a ssh option, this can be reused - KSshProcess::SshOptList opts; // list of SshOpts - KSshProcess::SshOptListIterator passwdIt; // points to the opt in opts that specifies the password - KSshProcess::SshOptListIterator usernameIt; - -// opt.opt = KSshProcess::SSH_VERBOSE; -// opts.append(opt); -// opts.append(opt); - - if( mPort != -1 ) { - opt.opt = KSshProcess::SSH_PORT; - opt.num = mPort; - opts.append(opt); + if (openPassDlg(pubKeyInfo, errMsg)) { + if (len < pubKeyInfo.password.utf8().length()+1) { + kdDebug(TDEIO_SFTP_DB) << "Insufficient buffer size for password: " << len + << " (" << pubKeyInfo.password.utf8().length()+1 << "needed)" << endl; } - opt.opt = KSshProcess::SSH_SUBSYSTEM; - opt.str = "sftp"; - opts.append(opt); - - opt.opt = KSshProcess::SSH_FORWARDX11; - opt.boolean = false; - opts.append(opt); + strncpy(buf, pubKeyInfo.password.utf8().data(), len-1); + buf[len-1]=0; // Just to be on the safe side - opt.opt = KSshProcess::SSH_FORWARDAGENT; - opt.boolean = false; - opts.append(opt); + purgeString(pubKeyInfo.password); - opt.opt = KSshProcess::SSH_PROTOCOL; - opt.num = 2; - opts.append(opt); - - opt.opt = KSshProcess::SSH_HOST; - opt.str = mHost; - opts.append(opt); - - opt.opt = KSshProcess::SSH_ESCAPE_CHAR; - opt.num = -1; // don't use any escape character - opts.append(opt); - - // set the username and password if we have them - if( !mUsername.isEmpty() ) { - opt.opt = KSshProcess::SSH_USERNAME; - opt.str = mUsername; - usernameIt = opts.append(opt); + // take a note that we already tried unlocking this keyfile + if(firstTry) { + mPubKeyAuthData.attemptedKeys.append(keyFile); } - if( !mPassword.isEmpty() ) { - opt.opt = KSshProcess::SSH_PASSWD; - opt.str = mPassword; - passwdIt = opts.append(opt); + // we consider publickey auth canceled only if we cancel all the key dialogs + mPubKeyAuthData.wasCanceled = false; + } else { + kdDebug(TDEIO_SFTP_DB) << "User canceled entry of public key passphrase" << endl; + rc = -1; + if (firstTimeCalled) { + mPubKeyAuthData.wasCanceled = true; } + } - ssh.setOptions(opts); - ssh.printArgs(); - - /////////////////////////////////////////////////////////////////////////// - // Start the ssh connection process. - // - - int err; // error code from KSshProcess - TQString msg; // msg for dialog box - TQString caption; // dialog box caption - bool firstTime = true; - bool dlgResult; - - while( !(mConnected = ssh.connect()) ) { - err = ssh.error(); - kdDebug(TDEIO_SFTP_DB) << "openConnection(): " - "Got " << err << " from KSshProcess::connect()" << endl; - - switch(err) { - case KSshProcess::ERR_NEED_PASSWD: - case KSshProcess::ERR_NEED_PASSPHRASE: - // At this point we know that either we didn't set - // an username or password in the ssh options list, - // or what we did pass did not work. Therefore we - // must prompt the user. - if( err == KSshProcess::ERR_NEED_PASSPHRASE ) - info.prompt = i18n("Please enter your username and key passphrase."); - else - info.prompt = i18n("Please enter your username and password."); - - kdDebug(TDEIO_SFTP_DB) << "openConnection(): info.username = " << info.username - << ", info.url = " << info.url.prettyURL() << endl; - - if( firstTime ) - dlgResult = openPassDlg(info); - else - dlgResult = openPassDlg(info, i18n("Incorrect username or password")); - - if( dlgResult ) { - if( info.username.isEmpty() || info.password.isEmpty() ) { - error(ERR_COULD_NOT_AUTHENTICATE, - i18n("Please enter a username and password")); - continue; - } - } - else { - // user canceled or dialog failed to open - error(ERR_USER_CANCELED, TQString::null); - kdDebug(TDEIO_SFTP_DB) << "openConnection(): user canceled, dlgResult = " << dlgResult << endl; - closeConnection(); - return; - } - - firstTime = false; - - // Check if the username has changed. SSH only accepts - // the username at startup. If the username has changed - // we must disconnect ssh, change the SSH_USERNAME - // option, and reset the option list. We will also set - // the password option so the user is not prompted for - // it again. - if( mUsername != info.username ) { - kdDebug(TDEIO_SFTP_DB) << "openConnection(): Username changed from " - << mUsername << " to " << info.username << endl; - - ssh.disconnect(); - - // if we haven't yet added the username - // or password option to the ssh options list then - // the iterators will be equal to the empty iterator. - // Create the opts now and add them to the opt list. - if( usernameIt == KSshProcess::SshOptListIterator() ) { - kdDebug(TDEIO_SFTP_DB) << "openConnection(): " - "Adding username to options list" << endl; - opt.opt = KSshProcess::SSH_USERNAME; - usernameIt = opts.append(opt); - } - - if( passwdIt == KSshProcess::SshOptListIterator() ) { - kdDebug(TDEIO_SFTP_DB) << "openConnection(): " - "Adding password to options list" << endl; - opt.opt = KSshProcess::SSH_PASSWD; - passwdIt = opts.append(opt); - } - - (*usernameIt).str = info.username; - (*passwdIt).str = info.password; - ssh.setOptions(opts); - ssh.printArgs(); - } - else { // just set the password - ssh.setPassword(info.password); - } + return rc; +} - mUsername = info.username; - mPassword = info.password; +void sftpProtocol::log_callback(ssh_session session, int priority, + const char *message, void *userdata) { + (void) session; + (void) userdata; - break; + kdDebug(TDEIO_SFTP_DB) << "[" << priority << "] " << message << endl; +} - case KSshProcess::ERR_NEW_HOST_KEY: - caption = i18n("Warning: Cannot verify host's identity."); - msg = ssh.errorMsg(); - if( KMessageBox::Yes != messageBox(WarningYesNo, msg, caption) ) { - closeConnection(); - error(ERR_USER_CANCELED, TQString::null); - return; - } - ssh.acceptHostKey(true); - break; - - case KSshProcess::ERR_DIFF_HOST_KEY: - caption = i18n("Warning: Host's identity changed."); - msg = ssh.errorMsg(); - if( KMessageBox::Yes != messageBox(WarningYesNo, msg, caption) ) { - closeConnection(); - error(ERR_USER_CANCELED, TQString::null); - return; - } - ssh.acceptHostKey(true); - break; - - case KSshProcess::ERR_AUTH_FAILED: - infoMessage(i18n("Authentication failed.")); - error(ERR_COULD_NOT_LOGIN, i18n("Authentication failed.")); - return; - - case KSshProcess::ERR_AUTH_FAILED_NEW_KEY: - msg = ssh.errorMsg(); - error(ERR_COULD_NOT_LOGIN, msg); - return; - - case KSshProcess::ERR_AUTH_FAILED_DIFF_KEY: - msg = ssh.errorMsg(); - error(ERR_COULD_NOT_LOGIN, msg); - return; - - case KSshProcess::ERR_CLOSED_BY_REMOTE_HOST: - infoMessage(i18n("Connection failed.")); - caption = i18n("Connection closed by remote host."); - msg = ssh.errorMsg(); - messageBox(Information, msg, caption); - closeConnection(); - error(ERR_COULD_NOT_LOGIN, msg); - return; - - case KSshProcess::ERR_INTERACT: - case KSshProcess::ERR_INTERNAL: - case KSshProcess::ERR_UNKNOWN: - case KSshProcess::ERR_INVALID_STATE: - case KSshProcess::ERR_CANNOT_LAUNCH: - case KSshProcess::ERR_HOST_KEY_REJECTED: - default: - infoMessage(i18n("Connection failed.")); - caption = i18n("Unexpected SFTP error: %1").arg(err); - msg = ssh.errorMsg(); - messageBox(Information, msg, caption); - closeConnection(); - error(ERR_UNKNOWN, msg); - return; - } +int sftpProtocol::authenticatePublicKey(){ + kdDebug(TDEIO_SFTP_DB) << "Trying to authenticate with public key" << endl; + + // First let's do some cleanup + mPubKeyAuthData.attemptedKeys.clear(); + mPubKeyAuthData.current_seqNr = SlaveBase::s_seqNr; + mPubKeyAuthData.wasCalled = 0; + mPubKeyAuthData.wasCanceled = 0; + + int rc; + + while (1) { + mPubKeyAuthData.wasCalled = 0; + rc = ssh_userauth_publickey_auto(mSession, nullptr, nullptr); + + kdDebug(TDEIO_SFTP_DB) << "ssh_userauth_publickey_auto returned rc=" << rc + << " ssh_err=" << ssh_get_error_code(mSession) + << " (" << ssh_get_error(mSession) << ")" << endl; + if (rc == SSH_AUTH_DENIED) { + if (!mPubKeyAuthData.wasCalled) { + kdDebug(TDEIO_SFTP_DB) << "Passkey auth denied because it has no matching key" << endl; + break; /* rc == SSH_AUTH_DENIED */ + } else if (mPubKeyAuthData.wasCanceled) { + kdDebug(TDEIO_SFTP_DB) << "Passkey auth denied because user canceled" << endl; + rc = sftpProtocol::SSH_AUTH_CANCELED; + break; + } else { + kdDebug(TDEIO_SFTP_DB) << "User entered wrong passphrase for the key" << endl; + mPubKeyAuthData.current_seqNr = SlaveBase::s_seqNr; + // Try it again + } + } else { + // every other rc is either error or success + break; } + } - // catch all in case we did something wrong above - if( !mConnected ) { - error(ERR_INTERNAL, TQString::null); - return; - } + return rc; +} - // Now send init packet. - kdDebug(TDEIO_SFTP_DB) << "openConnection(): Sending SSH2_FXP_INIT packet." << endl; - TQByteArray p; - TQDataStream packet(p, IO_WriteOnly); - packet << (TQ_UINT32)5; // packet length - packet << (TQ_UINT8) SSH2_FXP_INIT; // packet type - packet << (TQ_UINT32)SSH2_FILEXFER_VERSION; // client version - - putPacket(p); - getPacket(p); - - TQDataStream s(p, IO_ReadOnly); - TQ_UINT32 version; - TQ_UINT8 type; - s >> type; - kdDebug(TDEIO_SFTP_DB) << "openConnection(): Got type " << type << endl; - - if( type == SSH2_FXP_VERSION ) { - s >> version; - kdDebug(TDEIO_SFTP_DB) << "openConnection(): Got server version " << version << endl; - - // XXX Get extensions here - sftpVersion = version; - - /* Server should return lowest common version supported by - * client and server, but double check just in case. - */ - if( sftpVersion > SSH2_FILEXFER_VERSION ) { - error(ERR_UNSUPPORTED_PROTOCOL, - i18n("SFTP version %1").arg(version)); - closeConnection(); - return; - } - } - else { - error(ERR_UNKNOWN, i18n("Protocol error.")); - closeConnection(); - return; - } +int sftpProtocol::authenticateKeyboardInteractive(bool noPaswordQuery) { + kdDebug(TDEIO_SFTP_DB) << "Entering keyboard interactive function" << endl; - // Login succeeded! - infoMessage(i18n("Successfully connected to %1").arg(mHost)); - info.url.setProtocol("sftp"); - info.url.setHost(mHost); - info.url.setPort(mPort); - info.url.setUser(mUsername); - info.username = mUsername; - info.password = mPassword; - kdDebug(TDEIO_SFTP_DB) << "sftpProtocol(): caching info.username = " << info.username << - ", info.url = " << info.url.prettyURL() << endl; - cacheAuthentication(info); - mConnected = true; - connected(); + int rc = SSH_AUTH_ERROR; - mPassword.fill('x'); - info.password.fill('x'); + bool retryDenied = false; // a flag to avoid infinite looping - return; -} + TQString cachablePassword; + PasswordPurger cachePurger(cachablePassword); -void sftpProtocol::closeConnection() { - kdDebug(TDEIO_SFTP_DB) << "closeConnection()" << endl; - ssh.disconnect(); - mConnected = false; -} + // Different prompts during a single pass should be queried with the same s_seqNr value + long current_seqNr = SlaveBase::s_seqNr; -void sftpProtocol::sftpCopyPut(const KURL& src, const KURL& dest, int permissions, bool overwrite) { + while (1) { + int n = 0; + int i = 0; - KDE_struct_stat buff; - TQCString file (TQFile::encodeName(src.path())); + rc = ssh_userauth_kbdint(mSession, NULL, NULL); - if (KDE_lstat(file.data(), &buff) == -1) { - error (ERR_DOES_NOT_EXIST, src.prettyURL()); - return; + if (rc == SSH_AUTH_DENIED) { // do nothing + kdDebug(TDEIO_SFTP_DB) << "kb-interactive auth was denied; retrying again" << endl; + if (retryDenied) { + // If we were denied update the s_seqNr + current_seqNr = SlaveBase::s_seqNr; + continue; + } else { + break; + } + } else if (rc != SSH_AUTH_INFO) { + kdDebug(TDEIO_SFTP_DB) << "Finishing kb-interactive auth rc=" << rc + << " ssh_err=" << ssh_get_error_code(mSession) + << " (" << ssh_get_error(mSession) << ")" << endl; + break; } - if (S_ISDIR (buff.st_mode)) { - error (ERR_IS_DIRECTORY, src.prettyURL()); - return; - } + // See "RFC4256 Section 3.3 User Interface" for meaning of the values + TQString name, instruction, prompt; + name = TQString::fromUtf8(ssh_userauth_kbdint_getname(mSession)); + instruction = TQString::fromUtf8(ssh_userauth_kbdint_getinstruction(mSession)); + n = ssh_userauth_kbdint_getnprompts(mSession); - int fd = KDE_open (file.data(), O_RDONLY); - if (fd == -1) { - error (ERR_CANNOT_OPEN_FOR_READING, src.prettyURL()); - return; + if (n>0) { + // If there is at least one prompt we will want to retry auth if we fail + retryDenied = true; } - totalSize (buff.st_size); - - sftpPut (dest, permissions, false, overwrite, fd); - - // Close the file descriptor... - ::close( fd ); -} - -void sftpProtocol::sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd ) { + kdDebug(TDEIO_SFTP_DB) << "name=" << name << " instruction=" << instruction + << " prompts:" << n << endl; - openConnection(); - if( !mConnected ) - return; + for (i = 0; i < n; ++i) { + char echo; + bool isPassword=false; + TQString answer; + TQString errMsg; - kdDebug(TDEIO_SFTP_DB) << "sftpPut(): " << dest - << ", resume=" << resume - << ", overwrite=" << overwrite << endl; + // restore the s_seqNr so it would be the same for all the prompts + SlaveBase::s_seqNr = current_seqNr; - KURL origUrl( dest ); - sftpFileAttr origAttr(remoteEncoding()); - bool origExists = false; + prompt = TQString::fromUtf8(ssh_userauth_kbdint_getprompt(mSession, i, &echo)); + kdDebug(TDEIO_SFTP_DB) << "prompt=" << prompt << " echo=" << TQString::number(echo) << endl; - // Stat original (without part ext) to see if it already exists - int code = sftpStat(origUrl, origAttr); + TDEIO::AuthInfo infoKbdInt = authInfo(); + infoKbdInt.realmValue = prompt; // each prompt will be treated on its own by kpasswdserver + infoKbdInt.keepPassword = false; - if( code == SSH2_FX_OK ) { - kdDebug(TDEIO_SFTP_DB) << "sftpPut(): <file> already exists" << endl; + if (!name.isEmpty()) { + infoKbdInt.caption = TQString(i18n("SFTP Login") + " - " + name); + } - // Delete remote file if its size is zero - if( origAttr.fileSize() == 0 ) { - if( sftpRemove(origUrl, true) != SSH2_FX_OK ) { - error(ERR_CANNOT_DELETE_ORIGINAL, origUrl.prettyURL()); - return; + // Those strings might or might not contain some sensitive information + PasswordPurger answerPurger{answer}; + PasswordPurger infoPurger{infoKbdInt.password}; + + if (!echo) { + // ssh server requests us to ask user a question without displaying an answer. In normal + // circumstances this is probably a password, but it might be something else depending + // on the server configuration. + if (prompt.lower().startsWith("password")) { + // We can assume that the ssh server asks for a password and we will handle that case + // with more care since it's what most users will see + isPassword = true; + if (noPaswordQuery) { // if we have a cached password we might use it + kdDebug(TDEIO_SFTP_DB) << "Using cached password" << endl; + answer = mPassword; + cachablePassword = mPassword; + purgeString(mPassword); // if we used up password purge it + } else { + infoKbdInt.prompt = i18n("Please enter your password."); + infoKbdInt.realmValue = TQString(); // passwords use generic realm + infoKbdInt.keepPassword = true; + + if (mPasswordWasPrompted) { + errMsg = i18n("Login failed: incorrect password or username.").append('\n'); } + mPasswordWasPrompted = true; + } + } else { + // If the server's request doesn't look like a password, keep the servers prompt but + // don't prompt for saving the answer + infoKbdInt.prompt = i18n("Please enter answer for the next request:"); + if (!instruction.isEmpty()) { + infoKbdInt.prompt.append("\n\n").append(instruction); + } + infoKbdInt.prompt.append("\n\n").append(prompt); + infoKbdInt.readOnly = true; // set username readonly (enable changing it only with password) } - else { - origExists = true; - } - } - else if( code != SSH2_FX_NO_SUCH_FILE ) { - processStatus(code, origUrl.prettyURL()); - return; - } - - // Do not waste time/resources with more remote stat calls if the file exists - // and we weren't instructed to overwrite it... - if( origExists && !overwrite ) { - error(ERR_FILE_ALREADY_EXIST, origUrl.prettyURL()); - return; - } - - // Stat file with part ext to see if it already exists... - KURL partUrl( origUrl ); - partUrl.setFileName( partUrl.fileName() + ".part" ); - - TQ_UINT64 offset = 0; - bool partExists = false; - bool markPartial = config()->readBoolEntry("MarkPartial", true); - - if( markPartial ) { - - sftpFileAttr partAttr(remoteEncoding()); - code = sftpStat(partUrl, partAttr); - if( code == SSH2_FX_OK ) { - kdDebug(TDEIO_SFTP_DB) << "sftpPut(): .part file already exists" << endl; - partExists = true; - offset = partAttr.fileSize(); - - // If for some reason, both the original and partial files exist, - // skip resumption just like we would if the size of the partial - // file is zero... - if( origExists || offset == 0 ) - { - if( sftpRemove(partUrl, true) != SSH2_FX_OK ) { - error(ERR_CANNOT_DELETE_PARTIAL, partUrl.prettyURL()); - return; - } - - if( sftpRename(origUrl, partUrl) != SSH2_FX_OK ) { - error(ERR_CANNOT_RENAME_ORIGINAL, origUrl.prettyURL()); - return; - } - - offset = 0; - } - else if( !overwrite && !resume ) { - if (fd != -1) - resume = (KDE_lseek(fd, offset, SEEK_SET) != -1); - else - resume = canResume( offset ); - - kdDebug(TDEIO_SFTP_DB) << "sftpPut(): can resume = " << resume - << ", offset = " << offset; - - if( !resume ) { - error(ERR_FILE_ALREADY_EXIST, partUrl.prettyURL()); - return; - } - } - else { - offset = 0; + if (answer.isNull()) { + if (openPassDlg(infoKbdInt, errMsg)) { + answer = infoKbdInt.password; + kdDebug(TDEIO_SFTP_DB) << "Got the answer from the password dialog" << endl; + + if (isPassword) { + TQString sshUser=sshUsername(); + if (infoKbdInt.username != sshUser) { + kdDebug(TDEIO_SFTP_DB) << "Username changed from " << sshUser + << " to " << infoKbdInt.username << endl; + mCachedUsername = infoKbdInt.username; + mPassword = infoKbdInt.password; + + return sftpProtocol::SSH_AUTH_NEED_RECONNECT; + } } + } else { + return sftpProtocol::SSH_AUTH_CANCELED; + } } - else if( code == SSH2_FX_NO_SUCH_FILE ) { - if( origExists && sftpRename(origUrl, partUrl) != SSH2_FX_OK ) { - error(ERR_CANNOT_RENAME_ORIGINAL, origUrl.prettyURL()); - return; - } - } - else { - processStatus(code, partUrl.prettyURL()); - return; + } else { + // ssh server asks for some clear-text information from a user (e.g. a one-time + // identification code) which should be echoed while user enters it. As for now tdeio has + // no means to handle that correctly, so we will have to be creative with the password + // dialog. + TQString newPrompt; + + if (!instruction.isEmpty()) { + newPrompt = instruction + "\n\n"; } - } + newPrompt.append(prompt).append("\n\n"); + newPrompt.append(i18n("Use the username input field to answer this question.")); + infoKbdInt.prompt = newPrompt; - // Determine the url we will actually write to... - KURL writeUrl (markPartial ? partUrl:origUrl); - - TQ_UINT32 pflags = 0; - if( overwrite && !resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_TRUNC; - else if( !overwrite && !resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_EXCL; - else if( overwrite && resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT; - else if( !overwrite && resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_APPEND; - - sftpFileAttr attr(remoteEncoding()); - TQByteArray handle; - - // Set the permissions of the file we write to if it didn't already exist - // and the permission info is supplied, i.e it is not -1 - if( !partExists && !origExists && permissions != -1) - attr.setPermissions(permissions); - - code = sftpOpen( writeUrl, pflags, attr, handle ); - if( code != SSH2_FX_OK ) { - - // Rename the file back to its original name if a - // put fails due to permissions problems... - if( markPartial && overwrite ) { - (void) sftpRename(partUrl, origUrl); - writeUrl = origUrl; - } + infoKbdInt.url.setUser(infoKbdInt.username); + infoKbdInt.username = TQString::null; - if( code == SSH2_FX_FAILURE ) { // assume failure means file exists - error(ERR_FILE_ALREADY_EXIST, writeUrl.prettyURL()); - return; - } - else { - processStatus(code, writeUrl.prettyURL()); - return; + infoKbdInt.readOnly = false; + + if (openPassDlg(infoKbdInt)) { + answer = infoKbdInt.username; + kdDebug(TDEIO_SFTP_DB) << "Got the answer from the password dialog: " << answer << endl; + } else { + return sftpProtocol::SSH_AUTH_CANCELED; } - } + } - long nbytes; - TQByteArray buff; + if (ssh_userauth_kbdint_setanswer(mSession, i, answer.utf8().data()) < 0) { + kdDebug(TDEIO_SFTP_DB) << "An error occurred setting the answer: " + << ssh_get_error(mSession) << endl; + return SSH_AUTH_ERROR; + } + } // for each ssh_userauth_kbdint_getprompt() + } // while (1) + + if (!mPasswordWasPrompted && !cachablePassword.isEmpty() && (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL)) { + // if the password was never prompted, it was never cached, so we should cache it manually + TDEIO::AuthInfo info = authInfo(); + info.password = cachablePassword; + info.keepPassword = false; + cacheAuthentication(info); + purgeString(info.password); + } - do { + return rc; +} - if( fd != -1 ) { - buff.resize( 16*1024 ); - if ( (nbytes = ::read(fd, buff.data(), buff.size())) > -1 ) - buff.resize( nbytes ); - } - else { - dataReq(); - nbytes = readData( buff ); - } +int sftpProtocol::authenticatePassword(bool noPaswordQuery) { + kdDebug(TDEIO_SFTP_DB) << "Trying to authenticate with password" << endl; - if( nbytes >= 0 ) { - if( (code = sftpWrite(handle, offset, buff)) != SSH2_FX_OK ) { - error(ERR_COULD_NOT_WRITE, dest.prettyURL()); - return; - } + AuthInfo info = authInfo(); + info.keepPassword = true; + info.prompt = i18n("Please enter your username and password."); - offset += nbytes; - processedSize(offset); - - /* Check if slave was killed. According to slavebase.h we - * need to leave the slave methods as soon as possible if - * the slave is killed. This allows the slave to be cleaned - * up properly. - */ - if( wasKilled() ) { - sftpClose(handle); - closeConnection(); - error(ERR_UNKNOWN, i18n("An internal error occurred. Please try again.")); - return; - } - } + PasswordPurger pPurger(info.password); - } while( nbytes > 0 ); + int rc; + do { + TQString errMsg; - if( nbytes < 0 ) { - sftpClose(handle); + if(noPaswordQuery) { // on the first try use cached password + info.password = mPassword; + purgeString(mPassword); + } else { + if (mPasswordWasPrompted) { + errMsg = i18n("Login failed: incorrect password or username.").append('\n'); + } - if( markPartial ) { - // Remove remote file if it smaller than our keep size - uint minKeepSize = config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); + mPasswordWasPrompted = true; - if( sftpStat(writeUrl, attr) == SSH2_FX_OK ) { - if( attr.fileSize() < minKeepSize ) { - sftpRemove(writeUrl, true); - } - } - } + // Handle user canceled or dialog failed to open... + if (!openPassDlg(info, errMsg)) { + kdDebug(TDEIO_SFTP_DB) << "User canceled password dialog" << endl; + return sftpProtocol::SSH_AUTH_CANCELED; + } - error( ERR_UNKNOWN, i18n("Unknown error was encountered while copying the file " - "to '%1'. Please try again.").arg(dest.host()) ); - return; + TQString sshUser=sshUsername(); + if (info.username != sshUser) { + kdDebug(TDEIO_SFTP_DB) << "Username changed from " << sshUser + << " to " << info.username << endl; + mCachedUsername = info.username; + mPassword = info.password; + // libssh doc says that most servers don't permit changing the username during + // authentication, so we should reinitialize the session here + return sftpProtocol::SSH_AUTH_NEED_RECONNECT; + } } - if( (code = sftpClose(handle)) != SSH2_FX_OK ) { - error(ERR_COULD_NOT_WRITE, writeUrl.prettyURL()); - return; - } + rc = ssh_userauth_password(mSession, NULL, info.password.utf8().data()); - // If wrote to a partial file, then remove the part ext - if( markPartial ) { - if( sftpRename(partUrl, origUrl) != SSH2_FX_OK ) { - error(ERR_CANNOT_RENAME_PARTIAL, origUrl.prettyURL()); - return; - } - } + } while (rc == SSH_AUTH_DENIED && !noPaswordQuery); - finished(); + if (!mPasswordWasPrompted && (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL)) { + // if the password was never prompted, it was never cached, so we should cache it manually + info.keepPassword = false; + cacheAuthentication(info); + } + return rc; } -void sftpProtocol::put ( const KURL& url, int permissions, bool overwrite, bool resume ){ - kdDebug(TDEIO_SFTP_DB) << "put(): " << url << ", overwrite = " << overwrite - << ", resume = " << resume << endl; - - sftpPut( url, permissions, resume, overwrite ); -} -void sftpProtocol::stat ( const KURL& url ){ - kdDebug(TDEIO_SFTP_DB) << "stat(): " << url << endl; +TQString sftpProtocol::sshUsername() { + int rc; + TQString rv; - openConnection(); - if( !mConnected ) - return; + char *ssh_username = NULL; + rc = ssh_options_get(mSession, SSH_OPTIONS_USER, &ssh_username); + if (rc == 0 && ssh_username && ssh_username[0]) { + rv = TQString::fromUtf8(ssh_username); + } + ssh_string_free_char(ssh_username); - // If the stat URL has no path, do not attempt to determine the real - // path and do a redirect. KRun will simply ignore such requests. - // Instead, simply return the mime-type as a directory... - if( !url.hasPath() ) { - UDSEntry entry; - UDSAtom atom; + return rv; +} - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = TQString::null; - entry.append( atom ); - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - entry.append( atom ); +TQString sftpProtocol::sshError(TQString errMsg) { + if (ssh_get_error_code(mSession)) { + errMsg.append("\n\n").append(i18n("SSH error: \"%1\" (%2)") + .arg(TQString::fromUtf8(ssh_get_error(mSession))).arg(ssh_get_error_code(mSession))); + } + return errMsg; +} - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - entry.append( atom ); +TDEIO::AuthInfo sftpProtocol::authInfo() { + TDEIO::AuthInfo rv; - atom.m_uds = TDEIO::UDS_USER; - atom.m_str = mUsername; - entry.append( atom ); - atom.m_uds = TDEIO::UDS_GROUP; - entry.append( atom ); + rv.url.setProtocol("sftp"); + rv.url.setHost(mHost); + rv.url.setPort(mPort); + rv.url.setUser(mUsername); - // no size - statEntry( entry ); - finished(); - return; - } + rv.caption = i18n("SFTP Login"); + rv.comment = "sftp://" + mHost + ':' + TQString::number(mPort); + rv.commentLabel = i18n("site:"); - int code; - sftpFileAttr attr(remoteEncoding()); - if( (code = sftpStat(url, attr)) != SSH2_FX_OK ) { - processStatus(code, url.prettyURL()); - return; - } - else { - //kdDebug() << "We sent and received stat packet ok" << endl; - attr.setFilename(url.fileName()); - statEntry(attr.entry()); - } + if(!mUsername.isEmpty()) { + rv.username = mUsername; + } if(!mCachedUsername.isEmpty()) { + rv.username = mCachedUsername; + } else if (mSession) { + rv.username = sshUsername(); + } - finished(); + // if username was specified in the address string it shouldn't be changed + if (!mUsername.isEmpty()) { + rv.readOnly = true; + } - kdDebug(TDEIO_SFTP_DB) << "stat: END" << endl; - return; + return rv; } +void sftpProtocol::reportError(const KURL &url, const int err) { + kdDebug(TDEIO_SFTP_DB) << "url = " << url.url() << " - err=" << err << endl; -void sftpProtocol::mimetype ( const KURL& url ){ - kdDebug(TDEIO_SFTP_DB) << "mimetype(): " << url << endl; + switch (err) { + case SSH_FX_OK: + break; + case SSH_FX_NO_SUCH_FILE: + case SSH_FX_NO_SUCH_PATH: + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + break; + case SSH_FX_PERMISSION_DENIED: + error(TDEIO::ERR_ACCESS_DENIED, url.prettyURL()); + break; + case SSH_FX_FILE_ALREADY_EXISTS: + error(TDEIO::ERR_FILE_ALREADY_EXIST, url.prettyURL()); + break; + case SSH_FX_INVALID_HANDLE: + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + break; + case SSH_FX_OP_UNSUPPORTED: + error(TDEIO::ERR_UNSUPPORTED_ACTION, url.prettyURL()); + break; + case SSH_FX_BAD_MESSAGE: + error(TDEIO::ERR_UNKNOWN, url.prettyURL()); + break; + default: + error(TDEIO::ERR_INTERNAL, url.prettyURL()); + break; + } +} - openConnection(); - if( !mConnected ) - return; +bool sftpProtocol::createUDSEntry(const TQString &filename, const TQByteArray &path, + UDSEntry &entry, short int details) { + mode_t type; + mode_t access; + char *link; - TQ_UINT32 pflags = SSH2_FXF_READ; - TQByteArray handle, mydata; - sftpFileAttr attr(remoteEncoding()); - int code; - if( (code = sftpOpen(url, pflags, attr, handle)) != SSH2_FX_OK ) { - error(ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); - return; - } + Q_ASSERT(entry.count() == 0); - TQ_UINT32 len = 1024; // Get first 1k for determining mimetype - TQ_UINT64 offset = 0; - code = SSH2_FX_OK; - while( offset < len && code == SSH2_FX_OK ) { - if( (code = sftpRead(handle, offset, len, mydata)) == SSH2_FX_OK ) { - data(mydata); - offset += mydata.size(); - processedSize(offset); + sftp_attributes sb = sftp_lstat(mSftp, path.data()); + if (sb == NULL) { + return false; + } - kdDebug(TDEIO_SFTP_DB) << "mimetype(): offset = " << offset << endl; - } + UDSAtom atom; + atom.m_uds = UDS_NAME; + atom.m_str = filename; + entry.append(atom); + + if (sb->type == SSH_FILEXFER_TYPE_SYMLINK) { + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + link = sftp_readlink(mSftp, path.data()); + if (link == NULL) { + sftp_attributes_free(sb); + return false; + } + atom.m_uds = UDS_LINK_DEST; + atom.m_str = TQFile::decodeName(link); + entry.append(atom); + delete link; + // A symlink -> follow it only if details > 1 + if (details > 1) { + sftp_attributes sb2 = sftp_stat(mSftp, path.data()); + if (sb2 == NULL) { + // It is a link pointing to nowhere + type = S_IFMT - 1; + access = S_IRWXU | S_IRWXG | S_IRWXO; + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = type; + entry.append(atom); + + atom.m_uds = UDS_ACCESS; + atom.m_long = access; + entry.append(atom); + + atom.m_uds = UDS_SIZE; + atom.m_long = 0LL; + entry.append(atom); + + goto notype; + } + sftp_attributes_free(sb); + sb = sb2; } + } + switch (sb->type) { + case SSH_FILEXFER_TYPE_REGULAR: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + break; + case SSH_FILEXFER_TYPE_DIRECTORY: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append(atom); + break; + case SSH_FILEXFER_TYPE_SYMLINK: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFLNK; + entry.append(atom); + break; + case SSH_FILEXFER_TYPE_SPECIAL: + case SSH_FILEXFER_TYPE_UNKNOWN: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFMT - 1; + entry.append(atom); + break; + } - data(TQByteArray()); - processedSize(offset); - sftpClose(handle); - finished(); - kdDebug(TDEIO_SFTP_DB) << "mimetype(): END" << endl; -} - - -void sftpProtocol::listDir(const KURL& url) { - kdDebug(TDEIO_SFTP_DB) << "listDir(): " << url << endl; + access = sb->permissions & 07777; + atom.m_uds = UDS_ACCESS; + atom.m_long = access; + entry.append(atom); + + atom.m_uds = UDS_SIZE; + atom.m_long = sb->size; + entry.append(atom); + +notype: + if (details > 0) { + if (sb->owner) { + atom.m_uds = UDS_USER; + atom.m_str = TQString::fromUtf8(sb->owner); + entry.append(atom); + } else { + atom.m_uds = UDS_USER; + atom.m_str = TQString::number(sb->uid); + entry.append(atom); + } + + if (sb->group) { + atom.m_uds = UDS_GROUP; + atom.m_str = TQString::fromUtf8(sb->group); + entry.append(atom); + } else { + atom.m_uds = UDS_GROUP; + atom.m_str = TQString::number(sb->gid); + entry.append(atom); + } + atom.m_uds = UDS_ACCESS_TIME; + atom.m_long = sb->atime; + entry.append(atom); + + atom.m_uds = UDS_MODIFICATION_TIME; + atom.m_long = sb->mtime; + entry.append(atom); + + atom.m_uds = UDS_MODIFICATION_TIME; + atom.m_long = sb->createtime; + entry.append(atom); + } - openConnection(); - if( !mConnected ) - return; + sftp_attributes_free(sb); - if( !url.hasPath() ) { - KURL newUrl ( url ); - if( sftpRealPath(url, newUrl) == SSH2_FX_OK ) { - kdDebug(TDEIO_SFTP_DB) << "listDir: Redirecting to " << newUrl << endl; - redirection(newUrl); - finished(); - return; - } - } + return true; +} - int code; - TQByteArray handle; +TQString sftpProtocol::canonicalizePath(const TQString &path) { + kdDebug(TDEIO_SFTP_DB) << "Path to canonicalize: " << path << endl; + TQString cPath; + char *sPath = NULL; - if( (code = sftpOpenDirectory(url, handle)) != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "listDir(): open directory failed" << endl; - processStatus(code, url.prettyURL()); - return; - } + if (path.isEmpty()) { + return cPath; + } + sPath = sftp_canonicalize_path(mSftp, path.utf8().data()); + if (sPath == NULL) { + kdDebug(TDEIO_SFTP_DB) << "Could not canonicalize path: " << path << endl; + return cPath; + } - code = SSH2_FX_OK; - while( code == SSH2_FX_OK ) { - code = sftpReadDir(handle, url); - if( code != SSH2_FX_OK && code != SSH2_FX_EOF ) - processStatus(code, url.prettyURL()); - kdDebug(TDEIO_SFTP_DB) << "listDir(): return code = " << code << endl; - } + cPath = TQFile::decodeName(sPath); + delete sPath; - if( (code = sftpClose(handle)) != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "listdir(): closing of directory failed" << endl; - processStatus(code, url.prettyURL()); - return; - } + kdDebug(TDEIO_SFTP_DB) << "Canonicalized path: " << cPath << endl; - finished(); - kdDebug(TDEIO_SFTP_DB) << "listDir(): END" << endl; + return cPath; } -/** Make a directory. - OpenSSH does not follow the internet draft for sftp in this case. - The format of the mkdir request expected by OpenSSH sftp server is: - uint32 id - string path - ATTR attr - */ -void sftpProtocol::mkdir(const KURL&url, int permissions){ +sftpProtocol::sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket) + : SlaveBase("tdeio_sftp", pool_socket, app_socket), + mConnected(false), mPort(-1), mSession(NULL), mSftp(NULL) { +#ifndef TQ_WS_WIN + kdDebug(TDEIO_SFTP_DB) << "pid = " << getpid() << endl; - kdDebug(TDEIO_SFTP_DB) << "mkdir() creating dir: " << url.path() << endl; + kdDebug(TDEIO_SFTP_DB) << "debug = " << getenv("TDEIO_SFTP_LOG_VERBOSITY") << endl; +#endif - openConnection(); - if( !mConnected ) - return; + mCallbacks = (ssh_callbacks) malloc(sizeof(struct ssh_callbacks_struct)); + if (mCallbacks == NULL) { + error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not allocate callbacks")); + return; + } + ZERO_STRUCTP(mCallbacks); - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); + mCallbacks->userdata = this; + mCallbacks->auth_function = ::auth_callback; + if (getenv("TDEIO_SFTP_LOG_VERBOSITY")) { + mCallbacks->log_function = ::log_callback; + } - sftpFileAttr attr(remoteEncoding()); + ssh_callbacks_init(mCallbacks); +} - if (permissions != -1) - attr.setPermissions(permissions); +sftpProtocol::~sftpProtocol() { +#ifndef TQ_WS_WIN + kdDebug(TDEIO_SFTP_DB) << "pid = " << getpid() << endl; +#endif + closeConnection(); - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + free(mCallbacks); - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << TQ_UINT32(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len + attr.size()); - s << (TQ_UINT8)SSH2_FXP_MKDIR; - s << id; - s.writeBytes(path.data(), len); - s << attr; + /* cleanup and shut down cryto stuff */ + ssh_finalize(); - kdDebug(TDEIO_SFTP_DB) << "mkdir(): packet size is " << p.size() << endl; + purgeString(mPassword); +} - putPacket(p); - getPacket(p); +void sftpProtocol::setHost(const TQString& h, int port, const TQString& user, const TQString& pass) { + kdDebug(TDEIO_SFTP_DB) << "setHost(): " << user << "@" << h << ":" << port << endl; - TQ_UINT8 type; - TQDataStream r(p, IO_ReadOnly); + if (mConnected) { + closeConnection(); + } - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "mkdir: sftp packet id mismatch" << endl; - error(ERR_COULD_NOT_MKDIR, path); - finished(); - return; - } + mHost = h; - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "mkdir(): unexpected packet type of " << type << endl; - error(ERR_COULD_NOT_MKDIR, path); - finished(); - return; + if (port > 0) { + mPort = port; + } else { + struct servent *pse; + if ((pse = getservbyname("ssh", "tcp") ) == NULL) { + mPort = 22; + } else { + mPort = ntohs(pse->s_port); } + } - int code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "mkdir(): failed with code " << code << endl; - - // Check if mkdir failed because the directory already exists so that - // we can return the appropriate message... - sftpFileAttr dirAttr(remoteEncoding()); - if ( sftpStat(url, dirAttr) == SSH2_FX_OK ) - { - error( ERR_DIR_ALREADY_EXIST, url.prettyURL() ); - return; - } - - error(ERR_COULD_NOT_MKDIR, path); - } + kdDebug(TDEIO_SFTP_DB) << "setHost(): mPort=" << mPort << endl; - finished(); + mUsername = user; + mPassword = pass; + mCachedUsername = TQString::null; } -void sftpProtocol::rename(const KURL& src, const KURL& dest, bool overwrite){ - kdDebug(TDEIO_SFTP_DB) << "rename(" << src << " -> " << dest << ")" << endl; - - if (!isSupportedOperation(SSH2_FXP_RENAME)) { - error(ERR_UNSUPPORTED_ACTION, - i18n("The remote host does not support renaming files.")); - return; - } - openConnection(); - if( !mConnected ) - return; +int sftpProtocol::initializeConnection() { + unsigned char *hash = NULL; // the server hash + char *hexa; + char *verbosity; + int rc, state; + int timeout_sec = 30, timeout_usec = 0; - // Always stat the destination before attempting to rename - // a file or a directory... - sftpFileAttr attr(remoteEncoding()); - int code = sftpStat(dest, attr); + mSession = ssh_new(); + if (mSession == NULL) { + error(TDEIO::ERR_INTERNAL, i18n("Could not create a new SSH session.")); + return SSH_ERROR; + } - // If the destination directory, exists tell it to the job - // so it the proper action can be presented to the user... - if( code == SSH2_FX_OK ) - { - if (!overwrite) - { - if ( S_ISDIR(attr.permissions()) ) - error( TDEIO::ERR_DIR_ALREADY_EXIST, dest.url() ); - else - error( TDEIO::ERR_FILE_ALREADY_EXIST, dest.url() ); - return; - } + kdDebug(TDEIO_SFTP_DB) << "Creating the SSH session and setting options" << endl; - // If overwrite is specified, then simply remove the existing file/dir first... - if( (code = sftpRemove( dest, !S_ISDIR(attr.permissions()) )) != SSH2_FX_OK ) - { - processStatus(code); - return; - } - } + // Set timeout + rc = ssh_options_set(mSession, SSH_OPTIONS_TIMEOUT, &timeout_sec); + if (rc < 0) { + kdDebug(TDEIO_SFTP_DB) << "Could not set a timeout."; + } + rc = ssh_options_set(mSession, SSH_OPTIONS_TIMEOUT_USEC, &timeout_usec); + if (rc < 0) { + kdDebug(TDEIO_SFTP_DB) << "Could not set a timeout in usec."; + } - // Do the renaming... - if( (code = sftpRename(src, dest)) != SSH2_FX_OK ) { - processStatus(code); - return; - } + // Don't use any compression + rc = ssh_options_set(mSession, SSH_OPTIONS_COMPRESSION_C_S, "none"); + if (rc < 0) { + kdDebug(TDEIO_SFTP_DB) << "Could not set compression client <- server."; + } - finished(); - kdDebug(TDEIO_SFTP_DB) << "rename(): END" << endl; -} + rc = ssh_options_set(mSession, SSH_OPTIONS_COMPRESSION_S_C, "none"); + if (rc < 0) { + kdDebug(TDEIO_SFTP_DB) << "Could not set compression server -> client."; + } -void sftpProtocol::symlink(const TQString& target, const KURL& dest, bool overwrite){ - kdDebug(TDEIO_SFTP_DB) << "symlink()" << endl; + // Set host and port + rc = ssh_options_set(mSession, SSH_OPTIONS_HOST, mHost.utf8().data()); + if (rc < 0) { + error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set host.")); + return SSH_ERROR; + } - if (!isSupportedOperation(SSH2_FXP_SYMLINK)) { - error(ERR_UNSUPPORTED_ACTION, - i18n("The remote host does not support creating symbolic links.")); - return; + if (mPort > 0) { + rc = ssh_options_set(mSession, SSH_OPTIONS_PORT, &mPort); + if (rc < 0) { + error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set port.")); + return SSH_ERROR; } + } - openConnection(); - if( !mConnected ) - return; - - int code; - bool failed = false; - if( (code = sftpSymLink(target, dest)) != SSH2_FX_OK ) { - if( overwrite ) { // try to delete the destination - sftpFileAttr attr(remoteEncoding()); - if( (code = sftpStat(dest, attr)) != SSH2_FX_OK ) { - failed = true; - } - else { - if( (code = sftpRemove(dest, !S_ISDIR(attr.permissions())) ) != SSH2_FX_OK ) { - failed = true; - } - else { - // XXX what if rename fails again? We have lost the file. - // Maybe rename dest to a temporary name first? If rename is - // successful, then delete? - if( (code = sftpSymLink(target, dest)) != SSH2_FX_OK ) - failed = true; - } - } - } - else if( code == SSH2_FX_FAILURE ) { - error(ERR_FILE_ALREADY_EXIST, dest.prettyURL()); - return; - } - else - failed = true; + // Set the username + if (!mCachedUsername.isEmpty() || !mUsername.isEmpty()) { + TQString username = !mCachedUsername.isEmpty() ? mCachedUsername : mUsername; + rc = ssh_options_set(mSession, SSH_OPTIONS_USER, username.utf8().data()); + if (rc < 0) { + error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set username.")); + return rc; } + } - // What error code do we return? Code for the original symlink command - // or for the last command or for both? The second one is implemented here. - if( failed ) - processStatus(code); + verbosity = getenv("TDEIO_SFTP_LOG_VERBOSITY"); + if (verbosity) { + rc = ssh_options_set(mSession, SSH_OPTIONS_LOG_VERBOSITY_STR, verbosity); + if (rc < 0) { + error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set log verbosity.")); + return rc; + } + } - finished(); -} + // Read ~/.ssh/config + rc = ssh_options_parse_config(mSession, NULL); + if (rc < 0) { + error(TDEIO::ERR_INTERNAL, i18n("Could not parse the config file.")); + return rc; + } -void sftpProtocol::chmod(const KURL& url, int permissions){ - TQString perms; - perms.setNum(permissions, 8); - kdDebug(TDEIO_SFTP_DB) << "chmod(" << url << ", " << perms << ")" << endl; + ssh_set_callbacks(mSession, mCallbacks); - openConnection(); - if( !mConnected ) - return; + kdDebug(TDEIO_SFTP_DB) << "Trying to connect to the SSH server" << endl; - sftpFileAttr attr(remoteEncoding()); + /* try to connect */ + rc = ssh_connect(mSession); + if (rc < 0) { + error(TDEIO::ERR_COULD_NOT_CONNECT, sshError()); + return rc; + } - if (permissions != -1) - attr.setPermissions(permissions); + kdDebug(TDEIO_SFTP_DB) << "Getting the SSH server hash" << endl; - int code; - if( (code = sftpSetStat(url, attr)) != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "chmod(): sftpSetStat failed with error " << code << endl; - if( code == SSH2_FX_FAILURE ) - error(ERR_CANNOT_CHMOD, TQString::null); - else - processStatus(code, url.prettyURL()); - } - finished(); -} + /* get the hash */ + ssh_key serverKey; +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 7, 90) + rc = ssh_get_publickey(mSession, &serverKey); +#else + rc = ssh_get_server_publickey(mSession, &serverKey); +#endif + if (rc<0) { + error(TDEIO::ERR_COULD_NOT_CONNECT, sshError()); + return rc; + } + size_t hlen; +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 8, 90) + rc = ssh_get_publickey_hash(serverKey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen); +#else + rc = ssh_get_publickey_hash(serverKey, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen); +#endif + if (rc<0) { + error(TDEIO::ERR_COULD_NOT_CONNECT, sshError()); + return rc; + } -void sftpProtocol::del(const KURL &url, bool isfile){ - kdDebug(TDEIO_SFTP_DB) << "del(" << url << ", " << (isfile?"file":"dir") << ")" << endl; + kdDebug(TDEIO_SFTP_DB) << "Checking if the SSH server is known" << endl; - openConnection(); - if( !mConnected ) - return; + /* check the server public key hash */ +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 7, 90) + state = ssh_is_server_known(mSession); +#else + state = ssh_session_is_known_server(mSession); +#endif + switch (state) { + case TDEIO_SSH_KNOWN_HOSTS_OK: + break; + case TDEIO_SSH_KNOWN_HOSTS_OTHER: + delete hash; + error(TDEIO::ERR_CONNECTION_BROKEN, i18n("The host key for this server was " + "not found, but another type of key exists.\n" + "An attacker might change the default server key to confuse your " + "client into thinking the key does not exist.\n" + "Please contact your system administrator.\n%1").arg(TQString::fromUtf8(ssh_get_error(mSession)))); + return SSH_ERROR; + case TDEIO_SSH_KNOWN_HOSTS_CHANGED: + hexa = ssh_get_hexa(hash, hlen); + delete hash; + /* TODO print known_hosts file, port? */ + error(TDEIO::ERR_CONNECTION_BROKEN, i18n("The host key for the server %1 has changed.\n" + "This could either mean that DNS SPOOFING is happening or the IP " + "address for the host and its host key have changed at the same time.\n" + "The fingerprint for the key sent by the remote host is:\n %2\n" + "Please contact your system administrator.\n%3").arg( + mHost).arg(TQString::fromUtf8(hexa)).arg(TQString::fromUtf8(ssh_get_error(mSession)))); + delete hexa; + return SSH_ERROR; + case TDEIO_SSH_KNOWN_HOSTS_NOT_FOUND: + case TDEIO_SSH_KNOWN_HOSTS_UNKNOWN: { + TQString msg; // msg for dialog box + TQString caption; // dialog box caption + hexa = ssh_get_hexa(hash, hlen); + delete hash; + caption = i18n("Warning: Cannot verify host's identity."); + msg = i18n("The authenticity of host %1 cannot be established.\n" + "The key fingerprint is: %2\n" + "Are you sure you want to continue connecting?").arg(mHost).arg(hexa); + delete hexa; + + if (KMessageBox::Yes != messageBox(WarningYesNo, msg, caption)) { + error(TDEIO::ERR_USER_CANCELED, TQString()); + return SSH_ERROR; + } - int code; - if( (code = sftpRemove(url, isfile)) != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "del(): sftpRemove failed with error code " << code << endl; - processStatus(code, url.prettyURL()); + /* write the known_hosts file */ + kdDebug(TDEIO_SFTP_DB) << "Adding server to known_hosts file." << endl; +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 7, 90) + if (ssh_write_knownhost(mSession) != SSH_OK) { +#else + if (ssh_session_update_known_hosts(mSession) != SSH_OK) { +#endif + error(TDEIO::ERR_USER_CANCELED, sshError()); + return SSH_ERROR; + } + break; } - finished(); -} + case TDEIO_SSH_KNOWN_HOSTS_ERROR: + delete hash; + error(TDEIO::ERR_COULD_NOT_CONNECT, sshError()); + return SSH_ERROR; + } -void sftpProtocol::slave_status() { - kdDebug(TDEIO_SFTP_DB) << "slave_status(): connected to " - << mHost << "? " << mConnected << endl; + kdDebug(TDEIO_SFTP_DB) << "Trying to authenticate with the server" << endl; - slaveStatus ((mConnected ? mHost : TQString::null), mConnected); + return SSH_OK; } -bool sftpProtocol::getPacket(TQByteArray& msg) { - TQByteArray buf(4096); - - // Get the message length... - ssize_t len = atomicio(ssh.stdioFd(), buf.data(), 4, true /*read*/); - if( len == 0 || len == -1 ) { - kdDebug(TDEIO_SFTP_DB) << "getPacket(): read of packet length failed, ret = " - << len << ", error =" << strerror(errno) << endl; - closeConnection(); - error( ERR_CONNECTION_BROKEN, mHost); - msg.resize(0); - return false; - } - - uint msgLen; - TQDataStream s(buf, IO_ReadOnly); - s >> msgLen; +void sftpProtocol::openConnection() { - //kdDebug(TDEIO_SFTP_DB) << "getPacket(): Message size = " << msgLen << endl; + if (mConnected) { + return; + } - msg.resize(0); + kdDebug(TDEIO_SFTP_DB) << "username=" << mUsername << ", host=" << mHost << ", port=" << mPort << endl; - TQBuffer b( msg ); - b.open( IO_WriteOnly ); + infoMessage(i18n("Opening SFTP connection to host %1:%2").arg(mHost).arg(mPort)); - while( msgLen ) { - len = atomicio(ssh.stdioFd(), buf.data(), kMin((uint)buf.size(), msgLen), true /*read*/); + if (mHost.isEmpty()) { + kdDebug(TDEIO_SFTP_DB) << "openConnection(): Need hostname..." << endl; + error(TDEIO::ERR_UNKNOWN_HOST, i18n("No hostname specified.")); + return; + } - if( len == 0 || len == -1) { - TQString errmsg; - if (len == 0) - errmsg = i18n("Connection closed"); - else - errmsg = i18n("Could not read SFTP packet"); - kdDebug(TDEIO_SFTP_DB) << "getPacket(): nothing to read, ret = " << - len << ", error =" << strerror(errno) << endl; - closeConnection(); - error(ERR_CONNECTION_BROKEN, errmsg); - b.close(); - return false; - } + // Check for cached authentication info if no password is specified... + if (mPassword.isEmpty()) { + AuthInfo info = authInfo(); - b.writeBlock(buf.data(), len); + kdDebug(TDEIO_SFTP_DB) << "checking cache: info.username = " << info.username + << ", info.url = " << info.url.prettyURL() << endl; - //kdDebug(TDEIO_SFTP_DB) << "getPacket(): Read Message size = " << len << endl; - //kdDebug(TDEIO_SFTP_DB) << "getPacket(): Copy Message size = " << msg.size() << endl; + if (checkCachedAuthentication(info)) { + kdDebug() << "using cached" << endl; + mCachedUsername = info.username; + mPassword = info.password; - msgLen -= len; + purgeString(info.password); //< not really necessary because of Qt's implicit data sharing } + } - b.close(); + mPasswordWasPrompted = false; + PasswordPurger pwPurger{mPassword}; - return true; -} + int rc; + ExitGuard connectionCloser([this](){ closeConnection(); }); -/** Send an sftp packet to stdin of the ssh process. */ -bool sftpProtocol::putPacket(TQByteArray& p){ -// kdDebug(TDEIO_SFTP_DB) << "putPacket(): size == " << p.size() << endl; - int ret; - ret = atomicio(ssh.stdioFd(), p.data(), p.size(), false /*write*/); - if( ret <= 0 ) { - kdDebug(TDEIO_SFTP_DB) << "putPacket(): write failed, ret =" << ret << - ", error = " << strerror(errno) << endl; - return false; + do { // A loop to restart connection when needed + // Start the ssh connection. + if (initializeConnection() < 0) { + return; } - return true; -} - -/** Used to have the server canonicalize any given path name to an absolute path. -This is useful for converting path names containing ".." components or relative -pathnames without a leading slash into absolute paths. -Returns the canonicalized url. */ -int sftpProtocol::sftpRealPath(const KURL& url, KURL& newUrl){ - - kdDebug(TDEIO_SFTP_DB) << "sftpRealPath(" << url << ", newUrl)" << endl; + // Try to authenticate (this required before calling ssh_auth_list()) + rc = ssh_userauth_none(mSession, NULL); + if (rc == SSH_AUTH_ERROR) { + error(TDEIO::ERR_COULD_NOT_LOGIN, sshError(i18n("Authentication failed (method: %1).") + .arg(i18n("none")))); + return; + } - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); + // Preinit the list of supported auth methods + static const auto authMethodsNormal = [](){ + std::vector<std::unique_ptr<SSHAuthMethod>> rv; + rv.emplace_back(std::unique_ptr<PublicKeyAuth>(new PublicKeyAuth)); + rv.emplace_back(std::unique_ptr<KeyboardInteractiveAuth>(new KeyboardInteractiveAuth)); + rv.emplace_back(std::unique_ptr<PasswordAuth>(new PasswordAuth)); + return rv; + }(); + + const static int supportedMethods = std::accumulate( + authMethodsNormal.begin(), authMethodsNormal.end(), + SSH_AUTH_METHOD_NONE, //< none is supported by default + [](int acc, const std::unique_ptr<SSHAuthMethod> &m){ return acc |= m->flag(); }); + + unsigned attemptedMethods = 0; + + // Backup of the value of the SlaveBase::s_seqNr. This is used to query different data values + // with openPassDlg() with the same seqNr. Otherwise it will result in the prompting of the pass + // dialog to the user in cases the values should be recovered from the cache. + // This is a bit hacky but necessary + long current_seqNr = SlaveBase::s_seqNr; + + while (rc != SSH_AUTH_SUCCESS) { + // Note this loop can rerun in case of multistage ssh authentication e.g. "password,publickey" + // which will require user to provide a valid password at first and then a valid public key. + // see AuthenticationMethods in man 5 sshd_config for more info + bool wasCanceled = false; + unsigned availableMethodes = ssh_auth_list(mSession); + + SlaveBase::s_seqNr = current_seqNr; + + if (!availableMethodes) { + // Technically libssh docs suggest that the server merely MAY send auth methods, but it's + // highly unclear what we should do in such case and it looks like openssh doesn't have an + // option for that, so let's just consider this server a jerk and don't talk to him anymore. + error(TDEIO::ERR_COULD_NOT_LOGIN, i18n("Authentication failed.\n" + "The server did not send any authentication methods!")); + return; + } else if (!(availableMethodes & supportedMethods)) { + error(TDEIO::ERR_COULD_NOT_LOGIN, i18n("Authentication failed.\n" + "The server sent only unsupported authentication methods (%1)!") + .arg(SSHAuthMethod::bitsetToStr(availableMethodes).join(", "))); + return; + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + const auto *authMethods = &authMethodsNormal; + + // If we have cached password we want try to use it before public key + if(!mPassword.isEmpty()) { + static const auto authMethodsWithPassword = []() { + std::vector<std::unique_ptr<SSHAuthMethod>> rv; + rv.emplace_back(std::unique_ptr<KeyboardInteractiveAuth>( + new KeyboardInteractiveAuth(/* noPasswordQuery = */true) ) ); + rv.emplace_back(std::unique_ptr<PasswordAuth>( + new PasswordAuth(/* noPasswordQuery = */true) ) ); + for (const auto &m: authMethodsNormal) { rv.emplace_back(m->clone()); } + return rv; + }(); + + authMethods = &authMethodsWithPassword; + } - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << TQ_UINT32(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_REALPATH; - s << id; - s.writeBytes(path.data(), len); + // Actually iterate over the list of methods and try them out + for (const auto &method: *authMethods) { + if (!(availableMethodes & method->flag())) { continue; } + + rc = method->authenticate( this ); + attemptedMethods |= method->flag(); + if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL) { + kdDebug(TDEIO_SFTP_DB) << "method=" << method->name() << ": auth " + << (rc == SSH_AUTH_SUCCESS ? "success" : "partial") << endl; + break; // either next auth method or continue on with the connect + } else if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_AGAIN) { + TQString errMsg = i18n("Authentication failed (method: %1).").arg(method->name()); + // SSH_AUTH_AGAIN returned in case of some errors when server hangs up unexpectedly like + // in case there were too many failed authentication attempts + if (rc == SSH_AUTH_AGAIN) { + errMsg.append("\n").append(i18n("Server is slow to respond or hung up unexpectedly.")); + } + error(TDEIO::ERR_COULD_NOT_LOGIN, sshError(errMsg)); + return; + } else if (rc == SSH_AUTH_CANCELED) { + kdDebug(TDEIO_SFTP_DB) << "method=" << method->name() << " was canceled by user" << endl; + // don't quit immediately due to that the user might have canceled one method to use another + wasCanceled = true; + } else if (rc == SSH_AUTH_NEED_RECONNECT) { + kdDebug(TDEIO_SFTP_DB) << "method=" << method->name() << " requested reconnection" << endl; + break; + } else if (rc == SSH_AUTH_DENIED) { + kdDebug(TDEIO_SFTP_DB) << "Auth for method=" << method->name() << " was denied" << endl; + // do nothing, just proceed with next auth method + } else { + // Shouldn't happen, but to be on the safe side better handle it + error(TDEIO::ERR_UNKNOWN, sshError(i18n("Authentication failed unexpectedly"))); + return; + } + } - putPacket(p); - getPacket(p); + // At this point rc values should be one of: + // SSH_AUTH_SUCCESS, SSH_AUTH_PARTIAL, SSH_AUTH_DENIED, SSH_AUTH_CANCELED or SSH_AUTH_NEED_RECONNECT + if(rc == SSH_AUTH_NEED_RECONNECT) { + closeConnection(); //< have to do it manually + break; + } else if (wasCanceled && (rc == SSH_AUTH_CANCELED || rc == SSH_AUTH_DENIED)) { + error(TDEIO::ERR_USER_CANCELED, TQString::null); + return; + } else if (rc != SSH_AUTH_SUCCESS && rc != SSH_AUTH_PARTIAL) { + TQString errMsg = i18n("Authentication denied (attempted methods: %1).") + .arg(SSHAuthMethod::bitsetToStr(attemptedMethods).join(", ")); + if (availableMethodes & ~supportedMethods) { + errMsg.append("\n") + .append(i18n("Note: server also declares some unsupported authentication methods (%1)") + .arg(SSHAuthMethod::bitsetToStr(availableMethodes & ~supportedMethods).join(", "))); + } + error(TDEIO::ERR_COULD_NOT_LOGIN, errMsg); + return; + } + } // while (rc != SSH_AUTH_SUCCESS) + } while(rc == SSH_AUTH_NEED_RECONNECT); - TQ_UINT8 type; - TQDataStream r(p, IO_ReadOnly); - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpRealPath: sftp packet id mismatch" << endl; - return -1; - } + // start sftp session + kdDebug(TDEIO_SFTP_DB) << "Trying to request the sftp session" << endl; + mSftp = sftp_new(mSession); + if (mSftp == NULL) { + error(TDEIO::ERR_COULD_NOT_LOGIN, i18n("Unable to request the SFTP subsystem. " + "Make sure SFTP is enabled on the server.")); + return; + } - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 code; - r >> code; - return code; - } + kdDebug(TDEIO_SFTP_DB) << "Trying to initialize the sftp session" << endl; + if (sftp_init(mSftp) < 0) { + error(TDEIO::ERR_COULD_NOT_LOGIN, i18n("Could not initialize the SFTP session.")); + return; + } - if( type != SSH2_FXP_NAME ) { - kdError(TDEIO_SFTP_DB) << "sftpRealPath(): unexpected packet type of " << type << endl; - return -1; - } + // Login succeeded! + infoMessage(i18n("Successfully connected to %1").arg(mHost)); - TQ_UINT32 count; - r >> count; - if( count != 1 ) { - kdError(TDEIO_SFTP_DB) << "sftpRealPath(): Bad number of file attributes for realpath command" << endl; - return -1; - } + //setTimeoutSpecialCommand(TDEIO_SFTP_SPECIAL_TIMEOUT); - TQCString newPath; - r >> newPath; + mConnected = true; + connectionCloser.abort(); - newPath.truncate(newPath.size()); - if (newPath.isEmpty()) - newPath = "/"; - newUrl.setPath(newPath); + connected(); - return SSH2_FX_OK; + return; } -sftpProtocol::Status sftpProtocol::doProcessStatus(TQ_UINT8 code, const TQString& message) -{ - Status res; - res.code = 0; - res.size = 0; - res.text = message; +void sftpProtocol::closeConnection() { + kdDebug(TDEIO_SFTP_DB) << "closeConnection()" << endl; - switch(code) - { - case SSH2_FX_OK: - case SSH2_FX_EOF: - break; - case SSH2_FX_NO_SUCH_FILE: - res.code = ERR_DOES_NOT_EXIST; - break; - case SSH2_FX_PERMISSION_DENIED: - res.code = ERR_ACCESS_DENIED; - break; - case SSH2_FX_FAILURE: - res.text = i18n("SFTP command failed for an unknown reason."); - res.code = ERR_UNKNOWN; - break; - case SSH2_FX_BAD_MESSAGE: - res.text = i18n("The SFTP server received a bad message."); - res.code = ERR_UNKNOWN; - break; - case SSH2_FX_OP_UNSUPPORTED: - res.text = i18n("You attempted an operation unsupported by the SFTP server."); - res.code = ERR_UNKNOWN; - break; - default: - res.text = i18n("Error code: %1").arg(code); - res.code = ERR_UNKNOWN; - } + sftp_free(mSftp); + mSftp = NULL; - return res; -} + ssh_disconnect(mSession); + mSession = NULL; -/** Process SSH_FXP_STATUS packets. */ -void sftpProtocol::processStatus(TQ_UINT8 code, const TQString& message){ - Status st = doProcessStatus( code, message ); - if( st.code != 0 ) - error( st.code, st.text ); + mConnected = false; } -/** Opens a directory handle for url.path. Returns true if succeeds. */ -int sftpProtocol::sftpOpenDirectory(const KURL& url, TQByteArray& handle){ - - kdDebug(TDEIO_SFTP_DB) << "sftpOpenDirectory(" << url << ", handle)" << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); +#if 0 +void sftpProtocol::special(const TQByteArray &data) { + int rc; + kdDebug(TDEIO_SFTP_DB) << "special(): polling"; + + /* + * channel_poll() returns the number of bytes that may be read on the + * channel. It does so by checking the input buffer and eventually the + * network socket for data to read. If the input buffer is not empty, it + * will not probe the network (and such not read packets nor reply to + * keepalives). + * + * As channel_poll can act on two specific buffers (a channel has two + * different stream: stdio and stderr), polling for data on the stderr + * stream has more chance of not being in the problematic case (data left + * in the buffer). Checking the return value (for >0) would be a good idea + * to debug the problem. + */ + rc = channel_poll(mSftp->channel, 0); + if (rc > 0) { + rc = channel_poll(mSftp->channel, 1); + } + + if (rc < 0) { + kdDebug(TDEIO_SFTP_DB) << "channel_poll failed: " << ssh_get_error(mSession) << endl; + } + + setTimeoutSpecialCommand(TDEIO_SFTP_SPECIAL_TIMEOUT); +} +#endif - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; +void sftpProtocol::statMime(const KURL &url) { + kdDebug(TDEIO_SFTP_DB) << "stat: " << url.url() << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_OPENDIR; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); + openConnection(); + if (!mConnected) { + error(TDEIO::ERR_CONNECTION_BROKEN, url.prettyURL()); + return; + } - putPacket(p); - getPacket(p); + const TQString path = url.path(); + const TQByteArray path_c = path.utf8(); - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + sftp_attributes sb = sftp_lstat(mSftp, path_c.data()); + if (sb == NULL) { + reportError(url, sftp_get_error(mSftp)); + return; + } - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpOpenDirectory: sftp packet id mismatch: " << - "expected " << expectedId << ", got " << id << endl; - return -1; - } + switch (sb->type) { + case SSH_FILEXFER_TYPE_DIRECTORY: + sftp_attributes_free(sb); + emit mimeType("inode/directory"); + return; + case SSH_FILEXFER_TYPE_SPECIAL: + case SSH_FILEXFER_TYPE_UNKNOWN: + error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); + sftp_attributes_free(sb); + return; + case SSH_FILEXFER_TYPE_SYMLINK: + case SSH_FILEXFER_TYPE_REGULAR: + break; + } - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - return errCode; - } + size_t fileSize = sb->size; + sftp_attributes_free(sb); - if( type != SSH2_FXP_HANDLE ) { - kdError(TDEIO_SFTP_DB) << "sftpOpenDirectory: unexpected message type of " << type << endl; - return -1; - } + int flags = 0; - r >> handle; - if( handle.size() > 256 ) { - kdError(TDEIO_SFTP_DB) << "sftpOpenDirectory: handle exceeds max length" << endl; - return -1; - } + flags = O_RDONLY; - kdDebug(TDEIO_SFTP_DB) << "sftpOpenDirectory: handle (" << handle.size() << "): [" << handle << "]" << endl; - return SSH2_FX_OK; -} + mOpenFile = sftp_open(mSftp, path_c.data(), flags, 0); -/** Closes a directory or file handle. */ -int sftpProtocol::sftpClose(const TQByteArray& handle){ + if (mOpenFile == NULL) { + error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, path); + return; + } - kdDebug(TDEIO_SFTP_DB) << "sftpClose()" << endl; + // Determine the mimetype of the file to be retrieved, and emit it. + // This is mandatory in all slaves (for KRun/BrowserRun to work). + // If we're not opening the file ReadOnly or ReadWrite, don't attempt to + // read the file and send the mimetype. + size_t bytesRequested = 1024; + ssize_t bytesRead = 0; + TQByteArray buffer(bytesRequested); + + bytesRead = sftp_read(mOpenFile, buffer.data(), bytesRequested); + if (bytesRead < 0) { + error(TDEIO::ERR_COULD_NOT_READ, mOpenUrl.prettyURL()); + closeFile(); + return; + } else { + TQByteArray fileData; + fileData.setRawData(buffer.data(), bytesRead); + KMimeMagicResult *p_mimeType = KMimeMagic::self()->findBufferFileType(fileData, mOpenUrl.fileName()); + emit mimeType(p_mimeType->mimeType()); + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + sftp_close(mOpenFile); - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + handle.size()); - s << (TQ_UINT8)SSH2_FXP_CLOSE; - s << (TQ_UINT32)id; - s << handle; + mOpenFile = NULL; +} - putPacket(p); - getPacket(p); +#if 0 +void sftpProtocol::read(TDEIO::filesize_t bytes) { + kdDebug(TDEIO_SFTP_DB) << "read, offset = " << openOffset << ", bytes = " << bytes; - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + Q_ASSERT(mOpenFile != NULL); - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpClose: sftp packet id mismatch" << endl; - return -1; - } + TQVarLengthArray<char> buffer(bytes); - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "sftpClose: unexpected message type of " << type << endl; - return -1; - } + ssize_t bytesRead = sftp_read(mOpenFile, buffer.data(), bytes); + Q_ASSERT(bytesRead <= static_cast<ssize_t>(bytes)); - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "sftpClose: close failed with err code " << code << endl; - } + if (bytesRead < 0) { + kdDebug(TDEIO_SFTP_DB) << "Could not read " << mOpenUrl; + error(TDEIO::ERR_COULD_NOT_READ, mOpenUrl.prettyURL()); + close(); + return; + } - return code; + TQByteArray fileData = TQByteArray::fromRawData(buffer.data(), bytesRead); + data(fileData); } -/** Set a files attributes. */ -int sftpProtocol::sftpSetStat(const KURL& url, const sftpFileAttr& attr){ +void sftpProtocol::write(const TQByteArray &data) { + kdDebug(TDEIO_SFTP_DB) << "write, offset = " << openOffset << ", bytes = " << data.size(); - kdDebug(TDEIO_SFTP_DB) << "sftpSetStat(" << url << ", attr)" << endl; + Q_ASSERT(mOpenFile != NULL); - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + ssize_t bytesWritten = sftp_write(mOpenFile, data.data(), data.size()); + if (bytesWritten < 0) { + kdDebug(TDEIO_SFTP_DB) << "Could not write to " << mOpenUrl; + error(TDEIO::ERR_COULD_NOT_WRITE, mOpenUrl.prettyURL()); + close(); + return; + } - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len + attr.size()); - s << (TQ_UINT8)SSH2_FXP_SETSTAT; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - s << attr; + written(bytesWritten); +} - putPacket(p); - getPacket(p); +void sftpProtocol::seek(TDEIO::filesize_t offset) { + kdDebug(TDEIO_SFTP_DB) << "seek, offset = " << offset; - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + Q_ASSERT(mOpenFile != NULL); - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpSetStat(): sftp packet id mismatch" << endl; - return -1; - // XXX How do we do a fatal error? - } + if (sftp_seek64(mOpenFile, static_cast<uint64_t>(offset)) < 0) { + error(TDEIO::ERR_COULD_NOT_SEEK, mOpenUrl.path()); + close(); + } - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "sftpSetStat(): unexpected message type of " << type << endl; - return -1; - } + position(sftp_tell64(mOpenFile)); +} +#endif - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "sftpSetStat(): set stat failed with err code " << code << endl; - } +void sftpProtocol::closeFile() { + if (mOpenFile) { + sftp_close(mOpenFile); - return code; + mOpenFile = NULL; + finished(); + } } -/** Sends a sftp command to remove a file or directory. */ -int sftpProtocol::sftpRemove(const KURL& url, bool isfile){ - - kdDebug(TDEIO_SFTP_DB) << "sftpRemove(): " << url << ", isFile ? " << isfile << endl; +void sftpProtocol::get(const KURL& url) { + kdDebug(TDEIO_SFTP_DB) << "get(): " << url.url() << endl; - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); + openConnection(); + if (!mConnected) { + return; + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + TQByteArray path = url.path().utf8(); - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)(isfile ? SSH2_FXP_REMOVE : SSH2_FXP_RMDIR); - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); + char buf[MAX_XFER_BUF_SIZE] = {0}; + sftp_file file = NULL; + ssize_t bytesread = 0; + // time_t curtime = 0; + time_t lasttime = 0; + time_t starttime = 0; + ssize_t totalbytesread = 0; - putPacket(p); - getPacket(p); + sftp_attributes sb = sftp_lstat(mSftp, path.data()); + if (sb == NULL) { + reportError(url, sftp_get_error(mSftp)); + return; + } - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + switch (sb->type) { + case SSH_FILEXFER_TYPE_DIRECTORY: + error(TDEIO::ERR_IS_DIRECTORY, url.prettyURL()); + sftp_attributes_free(sb); + return; + case SSH_FILEXFER_TYPE_SPECIAL: + case SSH_FILEXFER_TYPE_UNKNOWN: + error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); + sftp_attributes_free(sb); + return; + case SSH_FILEXFER_TYPE_SYMLINK: + case SSH_FILEXFER_TYPE_REGULAR: + break; + } - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "del(): sftp packet id mismatch" << endl; - return -1; - } + // Open file + file = sftp_open(mSftp, path.data(), O_RDONLY, 0); + if (file == NULL) { + error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); + sftp_attributes_free(sb); + return; + } - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "del(): unexpected message type of " << type << endl; - return -1; + // Determine the mimetype of the file to be retrieved, and emit it. + // This is mandatory in all slaves (for KRun/BrowserRun to work) + // In real "remote" slaves, this is usually done using findByNameAndContent + // after receiving some data. But we don't know how much data the mimemagic rules + // need, so for local files, better use findByUrl with localUrl=true. + KMimeType::Ptr mt = KMimeType::findByURL( url, sb->permissions, false /* remote URL */ ); + emit mimeType( mt->name() ); // FIXME test me + + kdDebug(TDEIO_SFTP_DB) << "Total size: " << TQString::number(sb->size) << endl; + // Set the total size + totalSize(sb->size); + + const TQString resumeOffset = metaData(TQString("resume")); + if (!resumeOffset.isEmpty()) { + bool ok; + ssize_t offset = resumeOffset.toLong(&ok); + if (ok && (offset > 0) && ((unsigned long long) offset < sb->size)) + { + if (sftp_seek64(file, offset) == 0) { + canResume(); + totalbytesread = offset; + kdDebug(TDEIO_SFTP_DB) << "Resume offset: " << TQString::number(offset) << endl; + } } + } - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "del(): del failed with err code " << code << endl; - } + if (file != NULL) { + bool isFirstPacket = true; + lasttime = starttime = time(NULL); + + for (;;) { + bytesread = sftp_read(file, buf, MAX_XFER_BUF_SIZE); + kdDebug(TDEIO_SFTP_DB) << "bytesread=" << TQString::number(bytesread) << endl; + if (bytesread == 0) { + // All done reading + break; + } else if (bytesread < 0) { + kdDebug(TDEIO_SFTP_DB) << "Failed to read"; + error(TDEIO::ERR_COULD_NOT_READ, url.prettyURL()); + sftp_attributes_free(sb); + return; + } - return code; -} + TQByteArray filedata; + filedata.setRawData(buf, bytesread); + if (isFirstPacket) { + KMimeMagicResult *p_mimeType = KMimeMagic::self()->findBufferFileType(filedata, mOpenUrl.fileName()); + mimeType(p_mimeType->mimeType()); + kdDebug(TDEIO_SFTP_DB) << "mimetype=" << p_mimeType->mimeType() << endl; + isFirstPacket = false; + } + data(filedata); + filedata.resetRawData(buf, bytesread); -/** Send a sftp command to rename a file or directoy. */ -int sftpProtocol::sftpRename(const KURL& src, const KURL& dest){ + // increment total bytes read + totalbytesread += bytesread; - kdDebug(TDEIO_SFTP_DB) << "sftpRename(" << src << " -> " << dest << ")" << endl; + processedSize(totalbytesread); + } - TQCString srcPath = remoteEncoding()->encode(src.path()); - TQCString destPath = remoteEncoding()->encode(dest.path()); + kdDebug(TDEIO_SFTP_DB) << "size processed=" << totalbytesread << endl; + sftp_close(file); + //data(TQByteArray()); + processedSize((sb->size)); + } - uint slen = srcPath.length(); - uint dlen = destPath.length(); + sftp_attributes_free(sb); + finished(); +} - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; +void sftpProtocol::put(const KURL& url, int permissions, bool overwrite, bool resume) { + kdDebug(TDEIO_SFTP_DB) << "put(): " << url.url() + << " , permissions = " << TQString::number(permissions) + << ", overwrite = " << overwrite + << ", resume = " << resume << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + slen + - 4 /*str length*/ + dlen); - s << (TQ_UINT8)SSH2_FXP_RENAME; - s << (TQ_UINT32)id; - s.writeBytes(srcPath.data(), slen); - s.writeBytes(destPath.data(), dlen); + openConnection(); + if (!mConnected) { + return; + } - putPacket(p); - getPacket(p); + const TQString dest_orig = url.path(); + const TQByteArray dest_orig_c = dest_orig.utf8(); + const TQString dest_part = dest_orig + ".part"; + const TQByteArray dest_part_c = dest_part.utf8(); + uid_t owner = 0; + gid_t group = 0; + + sftp_attributes sb = sftp_lstat(mSftp, dest_orig_c.data()); + const bool bOrigExists = (sb != NULL); + bool bPartExists = false; + const bool bMarkPartial = config()->readEntry("MarkPartial", "true") == "true"; + + // Don't change permissions of the original file + if (bOrigExists) { + permissions = sb->permissions; + owner = sb->uid; + group = sb->gid; + } - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + if (bMarkPartial) { + sftp_attributes sbPart = sftp_lstat(mSftp, dest_part_c.data()); + bPartExists = (sbPart != NULL); - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpRename(): sftp packet id mismatch" << endl; - return -1; - } + if (bPartExists && !resume && !overwrite && + sbPart->size > 0 && sbPart->type == SSH_FILEXFER_TYPE_REGULAR) { + kdDebug(TDEIO_SFTP_DB) << "put : calling canResume with " + << TQString::number(sbPart->size) << endl; - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "sftpRename(): unexpected message type of " << type << endl; - return -1; - } + // Maybe we can use this partial file for resuming + // Tell about the size we have, and the app will tell us + // if it's ok to resume or not. + if (canResume(sbPart->size)) { + resume = true; + } - int code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "sftpRename(): rename failed with err code " << code << endl; - } + kdDebug(TDEIO_SFTP_DB) << "put got answer " << resume << endl; - return code; -} -/** Get directory listings. */ -int sftpProtocol::sftpReadDir(const TQByteArray& handle, const KURL& url){ - // url is needed so we can lookup the link destination - kdDebug(TDEIO_SFTP_DB) << "sftpReadDir(): " << url << endl; - - TQ_UINT32 id, expectedId, count; - TQ_UINT8 type; - - sftpFileAttr attr (remoteEncoding()); - attr.setDirAttrsFlag(true); - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - id = expectedId = mMsgId++; - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + handle.size()); - s << (TQ_UINT8)SSH2_FXP_READDIR; - s << (TQ_UINT32)id; - s << handle; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - r >> type >> id; - - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpReadDir(): sftp packet id mismatch" << endl; - return -1; + delete sbPart; } + } - int code; - if( type == SSH2_FXP_STATUS ) { - r >> code; - return code; + if (bOrigExists && !(overwrite) && !(resume)) { + if (sb->type == SSH_FILEXFER_TYPE_DIRECTORY) { + error(TDEIO::ERR_DIR_ALREADY_EXIST, dest_orig); + } else { + error(TDEIO::ERR_FILE_ALREADY_EXIST, dest_orig); } + sftp_attributes_free(sb); + return; + } - if( type != SSH2_FXP_NAME ) { - kdError(TDEIO_SFTP_DB) << "tdeio_sftpProtocl::sftpReadDir(): Unexpected message" << endl; - return -1; + int result; + TQByteArray dest; + sftp_file file = NULL; + + // Loop until we got 0 (end of data) + do { + TQByteArray buffer; + dataReq(); // Request for data + result = readData(buffer); + + if (result >= 0 && buffer.size()) { + kdDebug(TDEIO_SFTP_DB) << TQString("Got %1 bytes of data").arg(buffer.size()) << endl; + if (dest.isEmpty()) { + if (bMarkPartial) { + kdDebug(TDEIO_SFTP_DB) << "Appending .part extension to " << dest_orig << endl; + dest = dest_part_c; + if (bPartExists && !(resume)) { + kdDebug(TDEIO_SFTP_DB) << "Deleting partial file " << dest_part << endl; + sftp_unlink(mSftp, dest_part_c.data()); + // Catch errors when we try to open the file. + } + } else { + dest = dest_orig_c; + if (bOrigExists && !(resume)) { + kdDebug(TDEIO_SFTP_DB) << "Deleting destination file " << dest_orig << endl; + sftp_unlink(mSftp, dest_orig_c.data()); + // Catch errors when we try to open the file. + } + } // bMarkPartial + + if ((resume)) { + sftp_attributes fstat; + + kdDebug(TDEIO_SFTP_DB) << "Trying to append: " << dest.data() << endl; + file = sftp_open(mSftp, dest.data(), O_RDWR, 0); // append if resuming + if (file) { + fstat = sftp_fstat(file); + if (fstat) { + sftp_seek64(file, fstat->size); // Seek to end TODO + sftp_attributes_free(fstat); + } + } + } else { + mode_t initialMode; + + if (permissions != -1) { + initialMode = permissions | S_IWUSR | S_IRUSR; + } else { + initialMode = 0644; + } + + kdDebug(TDEIO_SFTP_DB) << "Trying to open: " << dest.data() << ", mode=" << TQString::number(initialMode) << endl; + file = sftp_open(mSftp, dest.data(), O_CREAT | O_TRUNC | O_WRONLY, initialMode); + } // resume + + if (file == NULL) { + kdDebug(TDEIO_SFTP_DB) << "COULD NOT WRITE " << dest.data() + << " permissions=" << permissions + << " error=" << ssh_get_error(mSession) << endl; + if (sftp_get_error(mSftp) == SSH_FX_PERMISSION_DENIED) { + error(TDEIO::ERR_WRITE_ACCESS_DENIED, TQString::fromUtf8(dest)); + } else { + error(TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, TQString::fromUtf8(dest)); + } + sftp_attributes_free(sb); + finished(); + return; + } // file + } // dest.isEmpty + + ssize_t bytesWritten = sftp_write(file, buffer.data(), buffer.size()); + kdDebug(TDEIO_SFTP_DB) << TQString("Written %1 bytes").arg(bytesWritten) << endl; + if (bytesWritten < 0) { + error(TDEIO::ERR_COULD_NOT_WRITE, dest_orig); + result = -1; + } + } // result + } while (result > 0); + sftp_attributes_free(sb); + + // An error occurred deal with it. + if (result < 0) { + kdDebug(TDEIO_SFTP_DB) << "Error during 'put'. Aborting." << endl; + + if (file != NULL) { + sftp_close(file); + + sftp_attributes attr = sftp_stat(mSftp, dest.data()); + if (bMarkPartial && attr != NULL) { + size_t size = config()->readLongNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); + if (attr->size < size) { + sftp_unlink(mSftp, dest.data()); + } + } + delete attr; + sftp_attributes_free(attr); } - r >> count; - kdDebug(TDEIO_SFTP_DB) << "sftpReadDir(): got " << count << " entries" << endl; + //::exit(255); + finished(); + return; + } - while(count--) { - r >> attr; + if (file == NULL) { // we got nothing to write out, so we never opened the file + finished(); + return; + } - if( S_ISLNK(attr.permissions()) ) { - KURL myurl ( url ); - myurl.addPath(attr.filename()); + if (sftp_close(file) < 0) { + kdWarning(TDEIO_SFTP_DB) << "Error when closing file descriptor" << endl; + error(TDEIO::ERR_COULD_NOT_WRITE, dest_orig); + return; + } - // Stat the symlink to find out its type... - sftpFileAttr attr2 (remoteEncoding()); - (void) sftpStat(myurl, attr2); + // after full download rename the file back to original name + if (bMarkPartial) { + // If the original URL is a symlink and we were asked to overwrite it, + // remove the symlink first. This ensures that we do not overwrite the + // current source if the symlink points to it. + if ((overwrite)) { + sftp_unlink(mSftp, dest_orig_c.data()); + } - attr.setLinkType(attr2.linkType()); - attr.setLinkDestination(attr2.linkDestination()); - } + if (sftp_rename(mSftp, dest.data(), dest_orig_c.data()) < 0) { + kdWarning(TDEIO_SFTP_DB) << " Couldn't rename " << dest.data() << " to " << dest_orig << endl; + error(TDEIO::ERR_CANNOT_RENAME_PARTIAL, dest_orig); + return; + } + } - listEntry(attr.entry(), false); + // set final permissions + if (permissions != -1 && !(resume)) { + kdDebug(TDEIO_SFTP_DB) << "Trying to set final permissions of " << dest_orig << " to " << TQString::number(permissions) << endl; + if (sftp_chmod(mSftp, dest_orig_c.data(), permissions) < 0) { + warning(i18n( "Could not change permissions for\n%1").arg(dest_orig)); } + } - listEntry(attr.entry(), true); + // set original owner and group + if (bOrigExists) { + kdDebug(TDEIO_SFTP_DB) << "Trying to restore original owner and group of " << dest_orig << endl; + if (sftp_chown(mSftp, dest_orig_c.data(), owner, group) < 0) { + // warning(i18n( "Could not change owner and group for\n%1", dest_orig)); + } + } - return SSH2_FX_OK; + // set modification time +#if 0 + const TQString mtimeStr = metaData("modified"); + if (!mtimeStr.isEmpty()) { + TQDateTime dt = TQDateTime::fromString(mtimeStr, TQt::ISODate); + if (dt.isValid()) { + struct timeval times[2]; + + sftp_attributes attr = sftp_lstat(mSftp, dest_orig_c.data()); + if (attr != NULL) { + times[0].tv_sec = attr->atime; //// access time, unchanged + times[1].tv_sec = dt.toTime_t(); // modification time + times[0].tv_usec = times[1].tv_usec = 0; + + sftp_utimes(mSftp, dest_orig_c.data(), times); + sftp_attributes_free(attr); + } + } + } +#endif + // We have done our job => finish + finished(); } -int sftpProtocol::sftpReadLink(const KURL& url, TQString& target){ - - kdDebug(TDEIO_SFTP_DB) << "sftpReadLink(): " << url << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - //kdDebug(TDEIO_SFTP_DB) << "sftpReadLink(): Encoded Path: " << path << endl; - //kdDebug(TDEIO_SFTP_DB) << "sftpReadLink(): Encoded Size: " << len << endl; - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; +void sftpProtocol::copy(const KURL &src, const KURL &dest, int permissions, bool overwrite) +{ + kdDebug(TDEIO_SFTP_DB) << src.url() << " -> " << dest.url() << " , permissions = " << TQString::number(permissions) + << ", overwrite = " << overwrite << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_READLINK; - s << id; - s.writeBytes(path.data(), len); + error(TDEIO::ERR_UNSUPPORTED_ACTION, TQString()); +} +void sftpProtocol::stat(const KURL& url) { + kdDebug(TDEIO_SFTP_DB) << url.url() << endl; - putPacket(p); - getPacket(p); + openConnection(); + if (!mConnected) { + return; + } - TQ_UINT8 type; - TQDataStream r(p, IO_ReadOnly); + if (! url.hasPath() || TQDir::isRelativePath(url.path()) || + url.path().contains("/./") || url.path().contains("/../")) { + TQString cPath; - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpReadLink(): sftp packet id mismatch" << endl; - return -1; + if (url.hasPath()) { + cPath = canonicalizePath(url.path()); + } else { + cPath = canonicalizePath(TQString(".")); } - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 code; - r >> code; - kdDebug(TDEIO_SFTP_DB) << "sftpReadLink(): read link failed with code " << code << endl; - return code; + if (cPath.isEmpty()) { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; } + KURL redir(url); + redir.setPath(cPath); + redirection(redir); - if( type != SSH2_FXP_NAME ) { - kdError(TDEIO_SFTP_DB) << "sftpReadLink(): unexpected packet type of " << type << endl; - return -1; - } + kdDebug(TDEIO_SFTP_DB) << "redirecting to " << redir.url() << endl; - TQ_UINT32 count; - r >> count; - if( count != 1 ) { - kdError(TDEIO_SFTP_DB) << "sftpReadLink(): Bad number of file attributes for realpath command" << endl; - return -1; - } + finished(); + return; + } - TQCString linkAddress; - r >> linkAddress; + TQByteArray path = url.path().utf8(); - linkAddress.truncate(linkAddress.size()); - kdDebug(TDEIO_SFTP_DB) << "sftpReadLink(): Link address: " << linkAddress << endl; + const TQString sDetails = metaData(TQString("details")); + const int details = sDetails.isEmpty() ? 2 : sDetails.toInt(); - target = remoteEncoding()->decode(linkAddress); + UDSEntry entry; + entry.clear(); + if (!createUDSEntry(url.fileName(), path, entry, details)) { + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + return; + } - return SSH2_FX_OK; -} + statEntry(entry); -int sftpProtocol::sftpSymLink(const TQString& _target, const KURL& dest){ + finished(); +} - TQCString destPath = remoteEncoding()->encode(dest.path()); - TQCString target = remoteEncoding()->encode(_target); - uint dlen = destPath.length(); - uint tlen = target.length(); +void sftpProtocol::mimetype(const KURL& url){ + kdDebug(TDEIO_SFTP_DB) << url.url() << endl; - kdDebug(TDEIO_SFTP_DB) << "sftpSymLink(" << target << " -> " << destPath << ")" << endl; + openConnection(); + if (!mConnected) { + return; + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + // stat() feeds the mimetype + statMime(url); + closeFile(); - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + tlen + - 4 /*str length*/ + dlen); - s << (TQ_UINT8)SSH2_FXP_SYMLINK; - s << (TQ_UINT32)id; - s.writeBytes(target.data(), tlen); - s.writeBytes(destPath.data(), dlen); + finished(); +} - putPacket(p); - getPacket(p); +void sftpProtocol::listDir(const KURL& url) { + kdDebug(TDEIO_SFTP_DB) << "list directory: " << url.url() << endl; - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + openConnection(); + if (!mConnected) { + return; + } - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpSymLink(): sftp packet id mismatch" << endl; - return -1; - } + if (! url.hasPath() || TQDir::isRelativePath(url.path()) || + url.path().contains("/./") || url.path().contains("/../")) { + TQString cPath; - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "sftpSymLink(): unexpected message type of " << type << endl; - return -1; + if (url.hasPath()) { + cPath = canonicalizePath(url.path()); + } else { + cPath = canonicalizePath(TQString(".")); } - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "sftpSymLink(): rename failed with err code " << code << endl; + if (cPath.isEmpty()) { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; } + KURL redir(url); + redir.setPath(cPath); + redirection(redir); - return code; -} - -/** Stats a file. */ -int sftpProtocol::sftpStat(const KURL& url, sftpFileAttr& attr) { + kdDebug(TDEIO_SFTP_DB) << "redirecting to " << redir.url() << endl; - kdDebug(TDEIO_SFTP_DB) << "sftpStat(): " << url << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); + finished(); + return; + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + TQByteArray path = url.path().utf8(); - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_LSTAT; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); + sftp_dir dp = sftp_opendir(mSftp, path.data()); + if (dp == NULL) { + reportError(url, sftp_get_error(mSftp)); + return; + } - putPacket(p); - getPacket(p); + sftp_attributes dirent = NULL; + const TQString sDetails = metaData(TQString("details")); + const int details = sDetails.isEmpty() ? 2 : sDetails.toInt(); + TQValueList<TQByteArray> entryNames; + UDSEntry entry; - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + kdDebug(TDEIO_SFTP_DB) << "readdir: " << path.data() << ", details: " << TQString::number(details) << endl; - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpStat(): sftp packet id mismatch" << endl; - return -1; - } + UDSAtom atom; - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - kdError(TDEIO_SFTP_DB) << "sftpStat(): stat failed with code " << errCode << endl; - return errCode; - } + for (;;) { + mode_t access; + mode_t type; + char *link; - if( type != SSH2_FXP_ATTRS ) { - kdError(TDEIO_SFTP_DB) << "sftpStat(): unexpected message type of " << type << endl; - return -1; + dirent = sftp_readdir(mSftp, dp); + if (dirent == NULL) { + break; } - r >> attr; - attr.setFilename(url.fileName()); - kdDebug(TDEIO_SFTP_DB) << "sftpStat(): " << attr << endl; + entry.clear(); + atom.m_uds = UDS_NAME; + atom.m_str = TQFile::decodeName(dirent->name); + entry.append(atom); - // If the stat'ed resource is a symlink, perform a recursive stat - // to determine the actual destination's type (file/dir). - if( S_ISLNK(attr.permissions()) && isSupportedOperation(SSH2_FXP_READLINK) ) { + if (dirent->type == SSH_FILEXFER_TYPE_SYMLINK) { + TQCString file = (TQString::fromUtf8(path) + "/" + TQFile::decodeName(dirent->name)).utf8().data(); - TQString target; - int code = sftpReadLink( url, target ); + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); - if ( code != SSH2_FX_OK ) { - kdError(TDEIO_SFTP_DB) << "sftpStat(): Unable to stat symlink destination" << endl; - return -1; + link = sftp_readlink(mSftp, file.data()); + if (link == NULL) { + sftp_attributes_free(dirent); + error(TDEIO::ERR_INTERNAL, i18n("Could not read link: %1").arg(TQString::fromUtf8(file))); + return; + } + atom.m_uds = UDS_LINK_DEST; + atom.m_str = TQFile::decodeName(link); + entry.append(atom); + delete link; + // A symlink -> follow it only if details > 1 + if (details > 1) { + sftp_attributes sb = sftp_stat(mSftp, file.data()); + if (sb == NULL) { + // It is a link pointing to nowhere + type = S_IFMT - 1; + access = S_IRWXU | S_IRWXG | S_IRWXO; + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = type; + entry.append(atom); + atom.m_uds = UDS_ACCESS; + atom.m_long = access; + entry.append(atom); + atom.m_uds = UDS_SIZE; + atom.m_long = 0; + entry.append(atom); + + goto notype; } + sftp_attributes_free(dirent); + dirent = sb; + } + } - kdDebug(TDEIO_SFTP_DB) << "sftpStat(): Resource is a symlink to -> " << target << endl; + switch (dirent->type) { + case SSH_FILEXFER_TYPE_REGULAR: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + break; + case SSH_FILEXFER_TYPE_DIRECTORY: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append(atom); + break; + case SSH_FILEXFER_TYPE_SYMLINK: + atom.m_uds = UDS_FILE_TYPE; + atom.m_long = S_IFLNK; + entry.append(atom); + break; + case SSH_FILEXFER_TYPE_SPECIAL: + case SSH_FILEXFER_TYPE_UNKNOWN: + break; + } + + access = dirent->permissions & 07777; + atom.m_uds = UDS_ACCESS; + atom.m_long = access; + entry.append(atom); + + atom.m_uds = UDS_SIZE; + atom.m_long = dirent->size; + entry.append(atom); + +notype: + if (details > 0) { + atom.m_uds = UDS_USER; + if (dirent->owner) { + atom.m_str = TQString::fromUtf8(dirent->owner); + } else { + atom.m_str = TQString::number(dirent->uid); + } + entry.append(atom); - KURL dest( url ); - if( target[0] == '/' ) - dest.setPath(target); - else - dest.setFileName(target); + atom.m_uds = UDS_GROUP; + if (dirent->group) { + atom.m_str = TQString::fromUtf8(dirent->group); + } else { + atom.m_str = TQString::number(dirent->gid); + } + entry.append(atom); - dest.cleanPath(); + atom.m_uds = UDS_ACCESS_TIME; + atom.m_long = dirent->atime; + entry.append(atom); - // Ignore symlinks that point to themselves... - if ( dest != url ) { + atom.m_uds = UDS_MODIFICATION_TIME; + atom.m_long = dirent->mtime; + entry.append(atom); - sftpFileAttr attr2 (remoteEncoding()); - (void) sftpStat(dest, attr2); + atom.m_uds = UDS_MODIFICATION_TIME; + atom.m_long = dirent->createtime; + entry.append(atom); + } - if (attr2.linkType() == 0) - attr.setLinkType(attr2.fileType()); - else - attr.setLinkType(attr2.linkType()); + sftp_attributes_free(dirent); + listEntry(entry, false); + } // for ever + sftp_closedir(dp); + listEntry(entry, true); // ready - attr.setLinkDestination(target); + finished(); +} - kdDebug(TDEIO_SFTP_DB) << "sftpStat(): File type: " << attr.fileType() << endl; - } - } +void sftpProtocol::mkdir(const KURL &url, int permissions) { + kdDebug(TDEIO_SFTP_DB) << "create directory: " << url.url() << endl; - return SSH2_FX_OK; -} + openConnection(); + if (!mConnected) { + return; + } + if (url.path().isEmpty()) { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + const TQString path = url.path(); + const TQByteArray path_c = path.utf8(); -int sftpProtocol::sftpOpen(const KURL& url, const TQ_UINT32 pflags, - const sftpFileAttr& attr, TQByteArray& handle) { - kdDebug(TDEIO_SFTP_DB) << "sftpOpen(" << url << ", handle" << endl; + // Remove existing file or symlink, if requested. + if (metaData(TQString("overwrite")) == TQString("true")) { + kdDebug(TDEIO_SFTP_DB) << "overwrite set, remove existing file or symlink: " << url.url() << endl; + sftp_unlink(mSftp, path_c.data()); + } - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); + kdDebug(TDEIO_SFTP_DB) << "Trying to create directory: " << path << endl; + sftp_attributes sb = sftp_lstat(mSftp, path_c.data()); + if (sb == NULL) { + if (sftp_mkdir(mSftp, path_c.data(), 0777) < 0) { + reportError(url, sftp_get_error(mSftp)); + sftp_attributes_free(sb); + return; + } else { + kdDebug(TDEIO_SFTP_DB) << "Successfully created directory: " << url.url() << endl; + if (permissions != -1) { + chmod(url, permissions); + } else { + finished(); + } + sftp_attributes_free(sb); + return; + } + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; + if (sb->type == SSH_FILEXFER_TYPE_DIRECTORY) { + error(TDEIO::ERR_DIR_ALREADY_EXIST, path); + } else { + error(TDEIO::ERR_FILE_ALREADY_EXIST, path); + } - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + len + - 4 /*pflags*/ + attr.size()); - s << (TQ_UINT8)SSH2_FXP_OPEN; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - s << pflags; - s << attr; + sftp_attributes_free(sb); + return; +} - putPacket(p); - getPacket(p); +void sftpProtocol::rename(const KURL& src, const KURL& dest, bool overwrite) { + kdDebug(TDEIO_SFTP_DB) << "rename " << src.url() << " to " << dest.url() << endl; - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + openConnection(); + if (!mConnected) { + return; + } - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpOpen(): sftp packet id mismatch" << endl; - return -1; - } + TQByteArray qsrc = src.path().utf8(); + TQByteArray qdest = dest.path().utf8(); - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - return errCode; + sftp_attributes sb = sftp_lstat(mSftp, qdest.data()); + if (sb != NULL) { + if (!overwrite) { + if (sb->type == SSH_FILEXFER_TYPE_DIRECTORY) { + error(TDEIO::ERR_DIR_ALREADY_EXIST, dest.url()); + } else { + error(TDEIO::ERR_FILE_ALREADY_EXIST, dest.url()); + } + sftp_attributes_free(sb); + return; } - if( type != SSH2_FXP_HANDLE ) { - kdError(TDEIO_SFTP_DB) << "sftpOpen(): unexpected message type of " << type << endl; - return -1; - } + del(dest, sb->type == SSH_FILEXFER_TYPE_DIRECTORY ? true : false); + } + sftp_attributes_free(sb); - r >> handle; - if( handle.size() > 256 ) { - kdError(TDEIO_SFTP_DB) << "sftpOpen(): handle exceeds max length" << endl; - return -1; - } + if (sftp_rename(mSftp, qsrc.data(), qdest.data()) < 0) { + reportError(dest, sftp_get_error(mSftp)); + return; + } - kdDebug(TDEIO_SFTP_DB) << "sftpOpen(): handle (" << handle.size() << "): [" << handle << "]" << endl; - return SSH2_FX_OK; + finished(); } +void sftpProtocol::symlink(const TQString& target, const KURL& dest, bool overwrite) { + kdDebug(TDEIO_SFTP_DB) << "link " << target << "->" << dest.url() + << ", overwrite = " << overwrite << endl; -int sftpProtocol::sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data) -{ - // kdDebug(TDEIO_SFTP_DB) << "sftpRead( offset = " << offset << ", len = " << len << ")" << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + handle.size() + - 8 /*offset*/ + 4 /*length*/); - s << (TQ_UINT8)SSH2_FXP_READ; - s << (TQ_UINT32)id; - s << handle; - s << offset; // we don't have a convienient 64 bit int so set upper int to zero - s << len; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpRead: sftp packet id mismatch" << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - kdError(TDEIO_SFTP_DB) << "sftpRead: read failed with code " << errCode << endl; - return errCode; - } + openConnection(); + if (!mConnected) { + return; + } - if( type != SSH2_FXP_DATA ) { - kdError(TDEIO_SFTP_DB) << "sftpRead: unexpected message type of " << type << endl; - return -1; + TQByteArray t = target.utf8(); + TQByteArray d = dest.path().utf8(); + + bool failed = false; + if (sftp_symlink(mSftp, t.data(), d.data()) < 0) { + if (overwrite) { + sftp_attributes sb = sftp_lstat(mSftp, d.data()); + if (sb == NULL) { + failed = true; + } else { + if (sftp_unlink(mSftp, d.data()) < 0) { + failed = true; + } else { + if (sftp_symlink(mSftp, t.data(), d.data()) < 0) { + failed = true; + } + } + } + sftp_attributes_free(sb); } + } - r >> data; + if (failed) { + reportError(dest, sftp_get_error(mSftp)); + return; + } - return SSH2_FX_OK; + finished(); } +void sftpProtocol::chmod(const KURL& url, int permissions) { + kdDebug(TDEIO_SFTP_DB) << "change permission of " << url.url() << " to " << TQString::number(permissions) << endl; -int sftpProtocol::sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data){ -// kdDebug(TDEIO_SFTP_DB) << "sftpWrite( offset = " << offset << -// ", data sz = " << data.size() << ")" << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); + openConnection(); + if (!mConnected) { + return; + } - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + handle.size() + - 8 /*offset*/ + - 4 /* data size */ + data.size()); - s << (TQ_UINT8)SSH2_FXP_WRITE; - s << (TQ_UINT32)id; - s << handle; - s << offset; // we don't have a convienient 64 bit int so set upper int to zero - s << data; + TQByteArray path = url.path().utf8(); -// kdDebug(TDEIO_SFTP_DB) << "sftpWrite(): SSH2_FXP_WRITE, id:" -// << id << ", handle:" << handle << ", offset:" << offset << ", some data" << endl; + if (sftp_chmod(mSftp, path.data(), permissions) < 0) { + reportError(url, sftp_get_error(mSftp)); + return; + } -// kdDebug(TDEIO_SFTP_DB) << "sftpWrite(): send packet [" << p << "]" << endl; + finished(); +} - putPacket(p); - getPacket(p); +void sftpProtocol::del(const KURL &url, bool isfile){ + kdDebug(TDEIO_SFTP_DB) << "deleting " << (isfile ? "file: " : "directory: ") << url.url() << endl; -// kdDebug(TDEIO_SFTP_DB) << "sftpWrite(): received packet [" << p << "]" << endl; + openConnection(); + if (!mConnected) { + return; + } - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; + TQByteArray path = url.path().utf8(); - r >> type >> id; - if( id != expectedId ) { - kdError(TDEIO_SFTP_DB) << "sftpWrite(): sftp packet id mismatch, got " - << id << ", expected " << expectedId << endl; - return -1; + if (isfile) { + if (sftp_unlink(mSftp, path.data()) < 0) { + reportError(url, sftp_get_error(mSftp)); + return; } - - if( type != SSH2_FXP_STATUS ) { - kdError(TDEIO_SFTP_DB) << "sftpWrite(): unexpected message type of " << type << endl; - return -1; + } else { + if (sftp_rmdir(mSftp, path.data()) < 0) { + reportError(url, sftp_get_error(mSftp)); + return; } + } - TQ_UINT32 code; - r >> code; - return code; + finished(); } - +void sftpProtocol::slave_status() { + kdDebug(TDEIO_SFTP_DB) << "connected to " << mHost << "?: " << mConnected << endl; + slaveStatus((mConnected ? mHost : TQString()), mConnected); +} diff --git a/tdeioslave/sftp/tdeio_sftp.h b/tdeioslave/sftp/tdeio_sftp.h index 30c452f9b..75b295cfd 100644 --- a/tdeioslave/sftp/tdeio_sftp.h +++ b/tdeioslave/sftp/tdeio_sftp.h @@ -1,59 +1,111 @@ -/*************************************************************************** - sftpProtocol.h - description - ------------------- - begin : Sat Jun 30 20:08:47 CDT 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu -***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ +/* + * Copyright (c) 2001 Lucas Fisher <ljfisher@purdue.edu> + * Copyright (c) 2009 Andreas Schneider <mail@cynapses.org> + * Copyright (c) 2020 Martin Sandsmark <martin@sandsmark.ninja> + * KDE2 port + * Copyright (c) 2022 Mavridis Philippe <mavridisf@gmail.com> + * Trinity port + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License (LGPL) as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later + * version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + #ifndef __tdeio_sftp_h__ #define __tdeio_sftp_h__ -#include <tqstring.h> -#include <tqcstring.h> -#include <tqobject.h> - #include <kurl.h> #include <tdeio/global.h> #include <tdeio/slavebase.h> #include <kdebug.h> +#include <stdint.h> +#include <memory> -#include "process.h" -#include "sftpfileattr.h" -#include "ksshprocess.h" +#include <libssh/libssh.h> +#include <libssh/sftp.h> +#include <libssh/callbacks.h> +// How big should each data packet be? Definitely not bigger than 64kb or +// you will overflow the 2 byte size variable in a sftp packet. +#define MAX_XFER_BUF_SIZE 60 * 1024 #define TDEIO_SFTP_DB 7120 +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 7, 90) +#define TDEIO_SSH_KNOWN_HOSTS_OK SSH_SERVER_KNOWN_OK +#define TDEIO_SSH_KNOWN_HOSTS_OTHER SSH_SERVER_FOUND_OTHER +#define TDEIO_SSH_KNOWN_HOSTS_CHANGED SSH_SERVER_KNOWN_CHANGED +#define TDEIO_SSH_KNOWN_HOSTS_NOT_FOUND SSH_SERVER_FILE_NOT_FOUND +#define TDEIO_SSH_KNOWN_HOSTS_UNKNOWN SSH_SERVER_NOT_KNOWN +#define TDEIO_SSH_KNOWN_HOSTS_ERROR SSH_SERVER_ERROR + +#else +#define TDEIO_SSH_KNOWN_HOSTS_OK SSH_KNOWN_HOSTS_OK +#define TDEIO_SSH_KNOWN_HOSTS_OTHER SSH_KNOWN_HOSTS_OTHER +#define TDEIO_SSH_KNOWN_HOSTS_CHANGED SSH_KNOWN_HOSTS_CHANGED +#define TDEIO_SSH_KNOWN_HOSTS_NOT_FOUND SSH_KNOWN_HOSTS_NOT_FOUND +#define TDEIO_SSH_KNOWN_HOSTS_UNKNOWN SSH_KNOWN_HOSTS_UNKNOWN +#define TDEIO_SSH_KNOWN_HOSTS_ERROR SSH_KNOWN_HOSTS_ERROR +#endif + +namespace TDEIO { + class AuthInfo; +} + class sftpProtocol : public TDEIO::SlaveBase { public: sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket); virtual ~sftpProtocol(); - virtual void setHost(const TQString& h, int port, const TQString& user, const TQString& pass); - virtual void get(const KURL& url); - virtual void listDir(const KURL& url) ; - virtual void mimetype(const KURL& url); - virtual void stat(const KURL& url); - virtual void copy(const KURL &src, const KURL &dest, int permissions, bool overwrite); - virtual void put(const KURL& url, int permissions, bool overwrite, bool resume); - virtual void closeConnection(); - virtual void slave_status(); - virtual void del(const KURL &url, bool isfile); - virtual void chmod(const KURL& url, int permissions); - virtual void symlink(const TQString& target, const KURL& dest, bool overwrite); - virtual void rename(const KURL& src, const KURL& dest, bool overwrite); - virtual void mkdir(const KURL&url, int permissions); - virtual void openConnection(); + virtual void setHost(const TQString& h, int port, const TQString& user, const TQString& pass) override; + virtual void get(const KURL& url) override; + virtual void listDir(const KURL& url) override; + virtual void mimetype(const KURL& url) override; + virtual void stat(const KURL& url) override; + virtual void put(const KURL& url, int permissions, bool overwrite, bool resume) override; + virtual void copy(const KURL &src, const KURL &dest, int permissions, bool overwrite) override; + virtual void closeConnection() override; + virtual void slave_status() override; + virtual void del(const KURL &url, bool isfile) override; + virtual void chmod(const KURL& url, int permissions) override; + virtual void symlink(const TQString& target, const KURL& dest, bool overwrite) override; + virtual void rename(const KURL& src, const KURL& dest, bool overwrite) override; + virtual void mkdir(const KURL& url, int permissions) override; + virtual void openConnection() override; + + // libssh authentication callback (note that this is called by the + // global ::auth_callback() call. + int auth_callback(const char *prompt, char *buf, size_t len, + int echo, int verify, void *userdata); + + // libssh logging callback (note that this is called by the + // global ::log_callback() call. + void log_callback(ssh_session session, int priority, const char *message, + void *userdata); + + // Callbacks for SSHAuthMethod-derived strategies + int authenticatePublicKey(); + int authenticateKeyboardInteractive(bool noPaswordQuery = false); + int authenticatePassword(bool noPaswordQuery = false); + + /** Some extra authentication failure reasons intended to use alongside was declared in libssh */ + enum extra_ssh_auth_e { + SSH_AUTH_CANCELED=128, //< user canceled password entry dialog + SSH_AUTH_NEED_RECONNECT //< it is required to reinitialize connection from scratch + }; private: // Private variables /** True if ioslave is connected to sftp server. */ @@ -65,85 +117,103 @@ private: // Private variables /** Port we are connected to. */ int mPort; - /** Ssh process to which we send the sftp packets. */ - KSshProcess ssh; + /** The ssh session for the connection */ + ssh_session mSession; - /** Username to use when connecting */ + /** The sftp session for the connection */ + sftp_session mSftp; + + /** Username to use when connecting, Note: it's the one passed in the URL */ TQString mUsername; - /** User's password */ + /** Username to use with the next connection attempt: it's either from the cached data or from + * the password dialog that was prompted to the user. */ + TQString mCachedUsername; + + /** User's password. Note: the password would be set only if it was somehow cached: passed to + * setHost(), received from passwdserver's cache or was entered by user before reconnection + */ TQString mPassword; - /** Message id of the last sftp packet we sent. */ - unsigned int mMsgId; + /** The open file */ + sftp_file mOpenFile; - /** Type of packet we are expecting to receive next. */ - unsigned char mExpected; + /** The open URL */ + KURL mOpenUrl; + + ssh_callbacks mCallbacks; /** Version of the sftp protocol we are using. */ int sftpVersion; - - struct Status - { - int code; - TDEIO::filesize_t size; - TQString text; - }; + + //struct Status + //{ + // int code; + // TDEIO::filesize_t size; + // TQString text; + //}; + + /** Some data needed to interact with auth_callback() */ + struct { + /** List of keys user was already prompted to enter the passphrase for. + * Note: Under most sane circumstances the list shouldn't go beyond size=2, + * so no fancy containers here + */ + TQStringList attemptedKeys; + /** A backup for SlaveBase::s_seqNr to pass the same value to prompts for different keys */ + long current_seqNr; + /** true if callback was called */ + bool wasCalled; + /** true if user canceled all passphrase entry dialogues */ + bool wasCanceled; + } mPubKeyAuthData; + + /** true if the password dialog was prompted to the user at leas once */ + bool mPasswordWasPrompted = false; private: // private methods - bool getPacket(TQByteArray& msg); + void statMime(const KURL &url); + void closeFile(); - /* Type is a sftp packet type found in .sftp.h'. - * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. - * - * Returns true if the type is supported by the sftp protocol - * version negotiated by the client and server (sftpVersion). - */ - bool isSupportedOperation(int type); - /** Used to have the server canonicalize any given path name to an absolute path. - This is useful for converting path names containing ".." components or relative - pathnames without a leading slash into absolute paths. - Returns the canonicalized url. */ - int sftpRealPath(const KURL& url, KURL& newUrl); - - /** Send an sftp packet to stdin of the ssh process. */ - bool putPacket(TQByteArray& p); - /** Process SSH_FXP_STATUS packets. */ - void processStatus(TQ_UINT8, const TQString& message = TQString::null); - /** Process SSH_FXP_STATUS packes and return the result. */ - Status doProcessStatus(TQ_UINT8, const TQString& message = TQString::null); - /** Opens a directory handle for url.path. Returns true if succeeds. */ - int sftpOpenDirectory(const KURL& url, TQByteArray& handle); - /** Closes a directory or file handle. */ - int sftpClose(const TQByteArray& handle); - /** Send a sftp command to rename a file or directoy. */ - int sftpRename(const KURL& src, const KURL& dest); - /** Set a files attributes. */ - int sftpSetStat(const KURL& url, const sftpFileAttr& attr); - /** Sends a sftp command to remove a file or directory. */ - int sftpRemove(const KURL& url, bool isfile); - /** Creates a symlink named dest to target. */ - int sftpSymLink(const TQString& target, const KURL& dest); - /** Get directory listings. */ - int sftpReadDir(const TQByteArray& handle, const KURL& url); - /** Retrieves the destination of a link. */ - int sftpReadLink(const KURL& url, TQString& target); - /** Stats a file. */ - int sftpStat(const KURL& url, sftpFileAttr& attr); - /** No descriptions */ - int sftpOpen(const KURL& url, const TQ_UINT32 pflags, const sftpFileAttr& attr, TQByteArray& handle); - /** No descriptions */ - int sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data); - /** No descriptions */ - int sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data); - - /** Performs faster upload when the source is a local file... */ - void sftpCopyPut(const KURL& src, const KURL& dest, int mode, bool overwrite); - /** Performs faster download when the destination is a local file... */ - void sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite); - - /** */ - Status sftpGet( const KURL& src, TDEIO::filesize_t offset = 0, int fd = -1); - void sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd = -1); + /** @returns username used by libssh during the connection */ + TQString sshUsername(); + + /** Adds ssh error (if any) to the given message string */ + TQString sshError(TQString errMsg=TQString()); + + /** A small helper function to construct auth info skeleton for the protocol */ + TDEIO::AuthInfo authInfo(); + + /** A helper function encapsulating creation of an ssh connection before authentication */ + int initializeConnection(); + + void reportError(const KURL &url, const int err); + + bool createUDSEntry(const TQString &filename, const TQByteArray &path, + TDEIO::UDSEntry &entry, short int details); + + TQString canonicalizePath(const TQString &path); }; + +/** A base class for ssh authentication methods. */ +class SSHAuthMethod { +public: + /** libssh's flag for he method */ + virtual unsigned flag() = 0; + /** The user-friendly (probably translated) name of the method */ + virtual TQString name() {return flagToStr(flag());} + /** Actually do perform the auth process */ + virtual int authenticate(sftpProtocol *ioslave) const = 0; + /** Creates a copy of derived class */ + virtual SSHAuthMethod* clone() = 0; + + virtual ~SSHAuthMethod() {}; + + /** Returns a name for the given libssh auth method flag */ + static TQString flagToStr(unsigned method); + + /** Returns a list of names for all the methods set in the given libssh auth method bitset */ + static TQStringList bitsetToStr(unsigned method); +}; + #endif diff --git a/tdeioslave/smb/tdeio_smb.h b/tdeioslave/smb/tdeio_smb.h index a81728d5d..56c296c31 100644 --- a/tdeioslave/smb/tdeio_smb.h +++ b/tdeioslave/smb/tdeio_smb.h @@ -94,7 +94,7 @@ class TDEProcess; class SMBSlave : public TQObject, public TDEIO::SlaveBase { - Q_OBJECT + TQ_OBJECT private: //--------------------------------------------------------------------- diff --git a/tdeioslave/smb/tdeio_smb_mount.cpp b/tdeioslave/smb/tdeio_smb_mount.cpp index 0aef92698..120372672 100644 --- a/tdeioslave/smb/tdeio_smb_mount.cpp +++ b/tdeioslave/smb/tdeio_smb_mount.cpp @@ -113,11 +113,11 @@ void SMBSlave::special( const TQByteArray & data) proc << TDEProcess::quote(mountPoint.local8Bit()); proc << options; - connect(&proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int )), - TQT_SLOT(readOutput(TDEProcess *, char *, int))); + connect(&proc, TQ_SIGNAL( receivedStdout(TDEProcess *, char *, int )), + TQ_SLOT(readOutput(TDEProcess *, char *, int))); - connect(&proc, TQT_SIGNAL( receivedStderr(TDEProcess *, char *, int )), - TQT_SLOT(readStdErr(TDEProcess *, char *, int))); + connect(&proc, TQ_SIGNAL( receivedStderr(TDEProcess *, char *, int )), + TQ_SLOT(readStdErr(TDEProcess *, char *, int))); if (!proc.start( TDEProcess::Block, TDEProcess::AllOutput )) { @@ -154,11 +154,11 @@ void SMBSlave::special( const TQByteArray & data) mybuf.truncate(0); mystderr.truncate(0); - connect(&proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int )), - TQT_SLOT(readOutput(TDEProcess *, char *, int))); + connect(&proc, TQ_SIGNAL( receivedStdout(TDEProcess *, char *, int )), + TQ_SLOT(readOutput(TDEProcess *, char *, int))); - connect(&proc, TQT_SIGNAL( receivedStderr(TDEProcess *, char *, int )), - TQT_SLOT(readStdErr(TDEProcess *, char *, int))); + connect(&proc, TQ_SIGNAL( receivedStderr(TDEProcess *, char *, int )), + TQ_SLOT(readStdErr(TDEProcess *, char *, int))); if ( !proc.start( TDEProcess::Block, TDEProcess::AllOutput ) ) { diff --git a/tdeioslave/smtp/CMakeLists.txt b/tdeioslave/smtp/CMakeLists.txt index 89ef650ca..d3d476ec4 100644 --- a/tdeioslave/smtp/CMakeLists.txt +++ b/tdeioslave/smtp/CMakeLists.txt @@ -35,7 +35,7 @@ tde_create_translated_desktop( set( target tdeio_smtp ) tde_add_kpart( ${target} AUTOMOC - SOURCES smtp.cc request.cc response.cc capabilities.cc command.cc transactionstate.cc + SOURCES smtp.cpp request.cpp response.cpp capabilities.cpp command.cpp transactionstate.cpp LINK tdeio-shared ${SASL_LIBRARIES} DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/smtp/Makefile.am b/tdeioslave/smtp/Makefile.am index 9859048b1..22cf859a1 100644 --- a/tdeioslave/smtp/Makefile.am +++ b/tdeioslave/smtp/Makefile.am @@ -3,7 +3,7 @@ INCLUDES= -I$(srcdir)/../.. -I$(srcdir)/.. $(SSL_INCLUDES) $(all_includes) kde_module_LTLIBRARIES = tdeio_smtp.la -tdeio_smtp_la_SOURCES = smtp.cc request.cc response.cc capabilities.cc command.cc transactionstate.cc +tdeio_smtp_la_SOURCES = smtp.cpp request.cpp response.cpp capabilities.cpp command.cpp transactionstate.cpp tdeio_smtp_la_LIBADD = $(LIB_TDEIO) $(SASL2_LIBS) tdeio_smtp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) @@ -16,22 +16,22 @@ TESTS = test_headergeneration test_responseparser test_commands check_PROGRAMS = $(TESTS) interactivesmtpserver -test_headergeneration_SOURCES = test_headergeneration.cc +test_headergeneration_SOURCES = test_headergeneration.cpp test_headergeneration_LDADD = $(LIB_TDECORE) test_headergeneration_LDFLAGS = $(all_libraries) -test_responseparser_SOURCES = test_responseparser.cc +test_responseparser_SOURCES = test_responseparser.cpp test_responseparser_LDADD = $(LIB_TDECORE) test_responseparser_LDFLAGS = $(all_libraries) -test_commands_SOURCES = test_commands.cc +test_commands_SOURCES = test_commands.cpp test_commands_LDADD = $(tdeio_smtp_la_LIBADD) test_commands_LDFLAGS = $(all_libraries) -interactivesmtpserver_SOURCES = interactivesmtpserver.cc +interactivesmtpserver_SOURCES = interactivesmtpserver.cpp interactivesmtpserver_LDADD = $(LIB_TQT) interactivesmtpserver_LDFLAGS = $(all_libraries) interactivesmtpserver_METASOURCES = AUTO messages: - $(XGETTEXT) *.cc -o $(podir)/tdeio_smtp.pot + $(XGETTEXT) *.cpp -o $(podir)/tdeio_smtp.pot diff --git a/tdeioslave/smtp/capabilities.cc b/tdeioslave/smtp/capabilities.cpp index f4f20fa7a..f0815c73e 100644 --- a/tdeioslave/smtp/capabilities.cc +++ b/tdeioslave/smtp/capabilities.cpp @@ -1,5 +1,5 @@ -/* -*- c++ -*- - capabilities.cc +/* + capabilities.cpp This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz <mutz@kde.org> diff --git a/tdeioslave/smtp/capabilities.h b/tdeioslave/smtp/capabilities.h index 1af13e365..eef6cc910 100644 --- a/tdeioslave/smtp/capabilities.h +++ b/tdeioslave/smtp/capabilities.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- +/* capabilities.h This file is part of tdeio_smtp, the KDE SMTP tdeioslave. diff --git a/tdeioslave/smtp/command.cc b/tdeioslave/smtp/command.cpp index 41bd8d58c..461cf520e 100644 --- a/tdeioslave/smtp/command.cc +++ b/tdeioslave/smtp/command.cpp @@ -1,5 +1,5 @@ -/* -*- c++ -*- - command.cc +/* + command.cpp This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz <mutz@kde.org> diff --git a/tdeioslave/smtp/command.h b/tdeioslave/smtp/command.h index c634d1a86..1f20be0e0 100644 --- a/tdeioslave/smtp/command.h +++ b/tdeioslave/smtp/command.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- +/* command.h This file is part of tdeio_smtp, the KDE SMTP tdeioslave. diff --git a/tdeioslave/smtp/interactivesmtpserver.cc b/tdeioslave/smtp/interactivesmtpserver.cpp index 5f25ca1ca..ed13d7253 100644 --- a/tdeioslave/smtp/interactivesmtpserver.cc +++ b/tdeioslave/smtp/interactivesmtpserver.cpp @@ -1,5 +1,5 @@ -/* -*- c++ -*- - interactivesmtpserver.cc +/* + interactivesmtpserver.cpp Code based on the serverSocket example by Jesper Pedersen. @@ -55,8 +55,8 @@ InteractiveSMTPServerWindow::~InteractiveSMTPServerWindow() { if ( mSocket ) { mSocket->close(); if ( mSocket->state() == TQSocket::Closing ) - connect( mSocket, TQT_SIGNAL(delayedCloseFinished()), - mSocket, TQT_SLOT(deleteLater()) ); + connect( mSocket, TQ_SIGNAL(delayedCloseFinished()), + mSocket, TQ_SLOT(deleteLater()) ); else mSocket->deleteLater(); mSocket = 0; @@ -108,17 +108,17 @@ InteractiveSMTPServerWindow::InteractiveSMTPServerWindow( TQSocket * socket, TQW hlay->addWidget( mLineEdit, 1 ); hlay->addWidget( but ); - connect( mLineEdit, TQT_SIGNAL(returnPressed()), TQT_SLOT(slotSendResponse()) ); - connect( but, TQT_SIGNAL(clicked()), TQT_SLOT(slotSendResponse()) ); + connect( mLineEdit, TQ_SIGNAL(returnPressed()), TQ_SLOT(slotSendResponse()) ); + connect( but, TQ_SIGNAL(clicked()), TQ_SLOT(slotSendResponse()) ); but = new TQPushButton( "&Close Connection", this ); vlay->addWidget( but ); - connect( but, TQT_SIGNAL(clicked()), TQT_SLOT(slotConnectionClosed()) ); + connect( but, TQ_SIGNAL(clicked()), TQ_SLOT(slotConnectionClosed()) ); - connect( socket, TQT_SIGNAL(connectionClosed()), TQT_SLOT(slotConnectionClosed()) ); - connect( socket, TQT_SIGNAL(error(int)), TQT_SLOT(slotError(int)) ); - connect( socket, TQT_SIGNAL(readyRead()), TQT_SLOT(slotReadyRead()) ); + connect( socket, TQ_SIGNAL(connectionClosed()), TQ_SLOT(slotConnectionClosed()) ); + connect( socket, TQ_SIGNAL(error(int)), TQ_SLOT(slotError(int)) ); + connect( socket, TQ_SIGNAL(readyRead()), TQ_SLOT(slotReadyRead()) ); mLineEdit->setText( "220 hi there" ); mLineEdit->setFocus(); diff --git a/tdeioslave/smtp/interactivesmtpserver.h b/tdeioslave/smtp/interactivesmtpserver.h index b4731d44c..c45a7cf56 100644 --- a/tdeioslave/smtp/interactivesmtpserver.h +++ b/tdeioslave/smtp/interactivesmtpserver.h @@ -1,7 +1,6 @@ #ifndef INTERACTIVESMTPSERVER_H #define INTERACTIVESMTPSERVER_H - -/* -*- c++ -*- +/* interactivesmtpserver.h Code based on the serverSocket example by Jesper Pedersen. @@ -67,7 +66,7 @@ static TQString trim( const TQString & s ) { class InteractiveSMTPServerWindow : public TQWidget { - Q_OBJECT + TQ_OBJECT public: InteractiveSMTPServerWindow( TQSocket * socket, TQWidget * parent=0, const char * name=0, WFlags f=0 ); ~InteractiveSMTPServerWindow(); @@ -103,7 +102,7 @@ private: }; class InteractiveSMTPServer : public TQServerSocket { - Q_OBJECT + TQ_OBJECT public: InteractiveSMTPServer( TQObject * parent=0 ); ~InteractiveSMTPServer() {} diff --git a/tdeioslave/smtp/request.cc b/tdeioslave/smtp/request.cpp index 4e3cde0e1..6d38fdd6e 100644 --- a/tdeioslave/smtp/request.cc +++ b/tdeioslave/smtp/request.cpp @@ -1,5 +1,5 @@ -/* -*- c++ -*- - request.cc +/* + request.cpp This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz <mutz@kde.org> diff --git a/tdeioslave/smtp/request.h b/tdeioslave/smtp/request.h index 37d74d2de..a007e3ab2 100644 --- a/tdeioslave/smtp/request.h +++ b/tdeioslave/smtp/request.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- +/* request.h This file is part of tdeio_smtp, the KDE SMTP tdeioslave. diff --git a/tdeioslave/smtp/response.cc b/tdeioslave/smtp/response.cpp index b630051de..de6b98868 100644 --- a/tdeioslave/smtp/response.cc +++ b/tdeioslave/smtp/response.cpp @@ -1,5 +1,5 @@ -/* -*- c++ -*- - response.cc +/* + response.cpp This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz <mutz@kde.org> diff --git a/tdeioslave/smtp/response.h b/tdeioslave/smtp/response.h index 97220661f..e65406aea 100644 --- a/tdeioslave/smtp/response.h +++ b/tdeioslave/smtp/response.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- +/* response.h This file is part of tdeio_smtp, the KDE SMTP tdeioslave. diff --git a/tdeioslave/smtp/smtp.cc b/tdeioslave/smtp/smtp.cpp index 00dff3684..ba009c1c5 100644 --- a/tdeioslave/smtp/smtp.cc +++ b/tdeioslave/smtp/smtp.cpp @@ -71,7 +71,6 @@ using KioSMTP::TransactionState; #include <tqcstring.h> #include <memory> -using std::auto_ptr; #include <ctype.h> #include <stdlib.h> @@ -446,8 +445,8 @@ void SMTPProtocol::queueCommand( int type ) { } bool SMTPProtocol::execute( int type, TransactionState * ts ) { - auto_ptr<Command> cmd( Command::createSimpleCommand( type, this ) ); - kdFatal( !cmd.get(), 7112 ) << "Command::createSimpleCommand( " << type << " ) returned null!" << endl; + std::unique_ptr<Command> cmd( Command::createSimpleCommand( type, this ) ); + kdFatal( !cmd, 7112 ) << "Command::createSimpleCommand( " << type << " ) returned null!" << endl; return execute( cmd.get(), ts ); } diff --git a/tdeioslave/smtp/smtp.h b/tdeioslave/smtp/smtp.h index e9d9b833b..9d324fe0c 100644 --- a/tdeioslave/smtp/smtp.h +++ b/tdeioslave/smtp/smtp.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- +/* * Copyright (c) 2000, 2001 Alex Zepeda <zipzippy@sonic.net> * Copyright (c) 2001 Michael H�ckel <Michael@Haeckel.Net> * All rights reserved. @@ -39,9 +39,7 @@ class KURL; class TQCString; template <typename T> class TQMemArray; -#ifdef USE_QT3 typedef TQMemArray<char> TQByteArray; -#endif // USE_QT3 namespace KioSMTP { class Response; diff --git a/tdeioslave/smtp/test_commands.cc b/tdeioslave/smtp/test_commands.cpp index d8a5f0d4e..61181bc35 100644 --- a/tdeioslave/smtp/test_commands.cc +++ b/tdeioslave/smtp/test_commands.cpp @@ -723,6 +723,6 @@ void checkSuccessfulTransferCommand( bool error, bool preload, bool ungetLast, #define NDEBUG -#include "command.cc" -#include "response.cc" -#include "transactionstate.cc" +#include "command.cpp" +#include "response.cpp" +#include "transactionstate.cpp" diff --git a/tdeioslave/smtp/test_headergeneration.cc b/tdeioslave/smtp/test_headergeneration.cpp index 83d999c4a..9e4cb971f 100644 --- a/tdeioslave/smtp/test_headergeneration.cc +++ b/tdeioslave/smtp/test_headergeneration.cpp @@ -82,5 +82,5 @@ int main( int , char ** ) { return result == expected ? 0 : 1 ; } -#include "request.cc" +#include "request.cpp" diff --git a/tdeioslave/smtp/test_responseparser.cc b/tdeioslave/smtp/test_responseparser.cpp index e251aa291..4786bc717 100644 --- a/tdeioslave/smtp/test_responseparser.cc +++ b/tdeioslave/smtp/test_responseparser.cpp @@ -104,4 +104,4 @@ int main ( int, char** ) { return 0; } -#include "response.cc" +#include "response.cpp" diff --git a/tdeioslave/smtp/transactionstate.cc b/tdeioslave/smtp/transactionstate.cpp index 58e5adf51..1d96e44b7 100644 --- a/tdeioslave/smtp/transactionstate.cc +++ b/tdeioslave/smtp/transactionstate.cpp @@ -1,5 +1,5 @@ -/* -*- c++ -*- - transactionstate.cc +/* + transactionstate.cpp This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz <mutz@kde.org> diff --git a/tdeioslave/smtp/transactionstate.h b/tdeioslave/smtp/transactionstate.h index ec39e3ac6..bf8a2a3bc 100644 --- a/tdeioslave/smtp/transactionstate.h +++ b/tdeioslave/smtp/transactionstate.h @@ -1,4 +1,4 @@ -/* -*- c++ -*- +/* transactionstate.h This file is part of tdeio_smtp, the KDE SMTP tdeioslave. diff --git a/tdeioslave/system/Makefile.am b/tdeioslave/system/Makefile.am index da49adca3..71475c4bc 100644 --- a/tdeioslave/system/Makefile.am +++ b/tdeioslave/system/Makefile.am @@ -27,5 +27,5 @@ check: testsystem ./testsystem messages: - $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_system.pot + $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_system.pot diff --git a/tdeioslave/system/systemimpl.cpp b/tdeioslave/system/systemimpl.cpp index 21a9da7da..164b9a467 100644 --- a/tdeioslave/system/systemimpl.cpp +++ b/tdeioslave/system/systemimpl.cpp @@ -279,12 +279,12 @@ void SystemImpl::createEntry(TDEIO::UDSEntry &entry, m_lastListingEmpty = true; TDEIO::ListJob *job = TDEIO::listDir(url, false, false); - connect( job, TQT_SIGNAL( entries(TDEIO::Job *, + connect( job, TQ_SIGNAL( entries(TDEIO::Job *, const TDEIO::UDSEntryList &) ), - this, TQT_SLOT( slotEntries(TDEIO::Job *, + this, TQ_SLOT( slotEntries(TDEIO::Job *, const TDEIO::UDSEntryList &) ) ); - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( slotResult(TDEIO::Job *) ) ); + connect( job, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( slotResult(TDEIO::Job *) ) ); tqApp->eventLoop()->enterLoop(); if (m_lastListingEmpty) icon = empty_icon; diff --git a/tdeioslave/system/systemimpl.h b/tdeioslave/system/systemimpl.h index 6270489c8..d4cc0e1cb 100644 --- a/tdeioslave/system/systemimpl.h +++ b/tdeioslave/system/systemimpl.h @@ -31,7 +31,7 @@ class SystemImpl : public TQObject { -Q_OBJECT +TQ_OBJECT public: SystemImpl(); diff --git a/tdeioslave/tar/CMakeLists.txt b/tdeioslave/tar/CMakeLists.txt index 30f2f6b1b..f08ac3aa9 100644 --- a/tdeioslave/tar/CMakeLists.txt +++ b/tdeioslave/tar/CMakeLists.txt @@ -35,7 +35,7 @@ tde_create_translated_desktop( set( target tdeio_tar ) tde_add_kpart( ${target} AUTOMOC - SOURCES tar.cc + SOURCES tar.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/tar/Makefile.am b/tdeioslave/tar/Makefile.am index 98acbb726..fdeb13c86 100644 --- a/tdeioslave/tar/Makefile.am +++ b/tdeioslave/tar/Makefile.am @@ -6,7 +6,7 @@ METASOURCES = AUTO kde_module_LTLIBRARIES = tdeio_tar.la -tdeio_tar_la_SOURCES = tar.cc +tdeio_tar_la_SOURCES = tar.cpp tdeio_tar_la_LIBADD = $(LIB_TDESYCOCA) tdeio_tar_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) @@ -21,4 +21,4 @@ kdelnk_DATA = tar.protocol ar.protocol zip.protocol kdelnkdir = $(kde_servicesdir) messages: - $(XGETTEXT) *.cc -o $(podir)/tdeio_tar.pot + $(XGETTEXT) *.cpp -o $(podir)/tdeio_tar.pot diff --git a/tdeioslave/tar/tar.cc b/tdeioslave/tar/tar.cpp index 6d71d8b21..b7ba70687 100644 --- a/tdeioslave/tar/tar.cc +++ b/tdeioslave/tar/tar.cpp @@ -619,5 +619,3 @@ debug("void TARProtocol::filterData"); } } */ - -// kate: space-indent on; indent-width 4; replace-tabs on; diff --git a/tdeioslave/thumbnail/exrcreator.cpp b/tdeioslave/thumbnail/exrcreator.cpp index 5708b8996..9ec2dd706 100644 --- a/tdeioslave/thumbnail/exrcreator.cpp +++ b/tdeioslave/thumbnail/exrcreator.cpp @@ -26,6 +26,7 @@ #include <tqfile.h> #include <ImfInputFile.h> +#include <ImfHeader.h> #include <ImfPreviewImage.h> #include "exrcreator.h" diff --git a/tdeioslave/thumbnail/htmlcreator.cpp b/tdeioslave/thumbnail/htmlcreator.cpp index 34742a0e9..5a6935010 100644 --- a/tdeioslave/thumbnail/htmlcreator.cpp +++ b/tdeioslave/thumbnail/htmlcreator.cpp @@ -50,7 +50,7 @@ bool HTMLCreator::create(const TQString &path, int width, int height, TQImage &i if (!m_html) { m_html = new TDEHTMLPart; - connect(m_html, TQT_SIGNAL(completed()), TQT_SLOT(slotCompleted())); + connect(m_html, TQ_SIGNAL(completed()), TQ_SLOT(slotCompleted())); m_html->setJScriptEnabled(false); m_html->setJavaEnabled(false); m_html->setPluginsEnabled(false); diff --git a/tdeioslave/thumbnail/htmlcreator.h b/tdeioslave/thumbnail/htmlcreator.h index 752cf0ace..052e1959e 100644 --- a/tdeioslave/thumbnail/htmlcreator.h +++ b/tdeioslave/thumbnail/htmlcreator.h @@ -27,7 +27,7 @@ class TDEHTMLPart; class HTMLCreator : public TQObject, public ThumbCreator { - Q_OBJECT + TQ_OBJECT public: HTMLCreator(); virtual ~HTMLCreator(); diff --git a/tdeioslave/thumbnail/thumbnail.cpp b/tdeioslave/thumbnail/thumbnail.cpp index cc2eefbc3..98b01138c 100644 --- a/tdeioslave/thumbnail/thumbnail.cpp +++ b/tdeioslave/thumbnail/thumbnail.cpp @@ -428,7 +428,7 @@ const TQImage& ThumbnailProtocol::getIcon() int h = icon->height(); for ( int y = 0; y < h; y++ ) { - QRgb *line = (QRgb *) icon->scanLine( y ); + TQRgb *line = (TQRgb *) icon->scanLine( y ); for ( int x = 0; x < w; x++ ) line[x] &= m_iconAlpha; // transparency } diff --git a/tdeioslave/trash/DESIGN b/tdeioslave/trash/DESIGN index 2bb6f19df..9420c53ce 100644 --- a/tdeioslave/trash/DESIGN +++ b/tdeioslave/trash/DESIGN @@ -13,7 +13,7 @@ BUGS TODO ==== -* Clean up konq_popupmenu.cc for Type=Link URL=trash:/ :( +* Clean up konq_popupmenu.cpp for Type=Link URL=trash:/ :( * Also, provide metainfo for trash contents for that desktop link. => maybe we need a new mimetype? Like application/x-trash-desktop, inheriting application/x-desktop. diff --git a/tdeioslave/trash/Makefile.am b/tdeioslave/trash/Makefile.am index 5d0d9b3e6..1c2ec23cc 100644 --- a/tdeioslave/trash/Makefile.am +++ b/tdeioslave/trash/Makefile.am @@ -31,7 +31,7 @@ testtrash_LDFLAGS = $(all_libraries) TESTS = testtrash messages: - $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_trash.pot + $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_trash.pot # ktrashpropsdlgplugin target noinst_HEADERS = ktrashpropsdlgplugin.h discspaceutil.h trash_constant.h diff --git a/tdeioslave/trash/discspaceutil.cpp b/tdeioslave/trash/discspaceutil.cpp index 186cb0e7f..e231b901c 100644 --- a/tdeioslave/trash/discspaceutil.cpp +++ b/tdeioslave/trash/discspaceutil.cpp @@ -102,9 +102,9 @@ void DiscSpaceUtil::done() void DiscSpaceUtil::calculateFullSize() { KDiskFreeSp *sp = KDiskFreeSp::findUsageInfo( mDirectory ); - connect( sp, TQT_SIGNAL( foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ) ), - this, TQT_SLOT( foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ) ) ); - connect( sp, TQT_SIGNAL( done() ), this, TQT_SLOT( done() ) ); + connect( sp, TQ_SIGNAL( foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ) ), + this, TQ_SLOT( foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ) ) ); + connect( sp, TQ_SIGNAL( done() ), this, TQ_SLOT( done() ) ); tqApp->eventLoop()->enterLoop(); } diff --git a/tdeioslave/trash/discspaceutil.h b/tdeioslave/trash/discspaceutil.h index a00141296..bcd8126e1 100644 --- a/tdeioslave/trash/discspaceutil.h +++ b/tdeioslave/trash/discspaceutil.h @@ -31,7 +31,7 @@ */ class DiscSpaceUtil : public TQObject { - Q_OBJECT + TQ_OBJECT public: /** diff --git a/tdeioslave/trash/kcmtrash.cpp b/tdeioslave/trash/kcmtrash.cpp index 4747e092a..8793be5d9 100644 --- a/tdeioslave/trash/kcmtrash.cpp +++ b/tdeioslave/trash/kcmtrash.cpp @@ -51,7 +51,7 @@ TrashModule::TrashModule(TQWidget *parent, const char *name) policyWidget = new KTrashPropsWidget(this); tab->addTab(policyWidget, i18n("&Trash Policy")); - connect(policyWidget, TQT_SIGNAL(changed(bool)), TQT_SIGNAL(changed(bool))); + connect(policyWidget, TQ_SIGNAL(changed(bool)), TQ_SIGNAL(changed(bool))); TQVBoxLayout *top = new TQVBoxLayout(this); top->addWidget(tab); diff --git a/tdeioslave/trash/kcmtrash.h b/tdeioslave/trash/kcmtrash.h index 4987ccfba..dc04b9587 100644 --- a/tdeioslave/trash/kcmtrash.h +++ b/tdeioslave/trash/kcmtrash.h @@ -27,7 +27,7 @@ class TQTabWidget; class TrashModule : public TDECModule { - Q_OBJECT + TQ_OBJECT public: TrashModule(TQWidget *parent, const char *name); diff --git a/tdeioslave/trash/ktrashpropsdlgplugin.cpp b/tdeioslave/trash/ktrashpropsdlgplugin.cpp index 067c10b6e..7b36aaaf4 100644 --- a/tdeioslave/trash/ktrashpropsdlgplugin.cpp +++ b/tdeioslave/trash/ktrashpropsdlgplugin.cpp @@ -74,7 +74,7 @@ KTrashPropsDlgPlugin::KTrashPropsDlgPlugin( KPropertiesDialog *dialog, const cha policyWidget = new KTrashPropsWidget(frame); TQVBoxLayout *vLayout = new TQVBoxLayout(frame, 0, 0); vLayout->addWidget(policyWidget); - connect(policyWidget, TQT_SIGNAL(changed(bool)), TQT_SLOT(setDirty())); + connect(policyWidget, TQ_SIGNAL(changed(bool)), TQ_SLOT(setDirty())); } KTrashPropsDlgPlugin::~KTrashPropsDlgPlugin() diff --git a/tdeioslave/trash/ktrashpropsdlgplugin.h b/tdeioslave/trash/ktrashpropsdlgplugin.h index b839f6428..b17c0d5f8 100644 --- a/tdeioslave/trash/ktrashpropsdlgplugin.h +++ b/tdeioslave/trash/ktrashpropsdlgplugin.h @@ -36,7 +36,7 @@ class KTrashPropsWidget; class KTrashPropsDlgPlugin : public KPropsDlgPlugin { - Q_OBJECT + TQ_OBJECT public: KTrashPropsDlgPlugin( KPropertiesDialog *dialog, const char*, const TQStringList& ); diff --git a/tdeioslave/trash/ktrashpropswidget.cpp b/tdeioslave/trash/ktrashpropswidget.cpp index 40e12cb4f..2040e9a76 100644 --- a/tdeioslave/trash/ktrashpropswidget.cpp +++ b/tdeioslave/trash/ktrashpropswidget.cpp @@ -50,15 +50,15 @@ KTrashPropsWidget::KTrashPropsWidget(TQWidget *parent, const char *name) mTrashImpl->init(); setupGui(); - connect(mUseTimeLimit, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(useTypeChanged())); - connect(mDays, TQT_SIGNAL(valueChanged(int)),this, TQT_SLOT(setDirty())); - connect(mUseSizeLimit, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(useTypeChanged())); - connect(mPercentSize, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(percentSizeChanged(double))); - connect(mFixedSize, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(fixedSizeChanged(double))); - connect(mFixedSizeUnit, TQT_SIGNAL(activated(int)), this, TQT_SLOT(fixedSizeUnitActivated(int))); - connect(mRbPercentSize, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(rbPercentSizeToggled(bool))); - connect(mRbFixedSize, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(rbFixedSizeToggled(bool))); - connect(mLimitReachedAction, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setDirty())); + connect(mUseTimeLimit, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(useTypeChanged())); + connect(mDays, TQ_SIGNAL(valueChanged(int)),this, TQ_SLOT(setDirty())); + connect(mUseSizeLimit, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(useTypeChanged())); + connect(mPercentSize, TQ_SIGNAL(valueChanged(double)), this, TQ_SLOT(percentSizeChanged(double))); + connect(mFixedSize, TQ_SIGNAL(valueChanged(double)), this, TQ_SLOT(fixedSizeChanged(double))); + connect(mFixedSizeUnit, TQ_SIGNAL(activated(int)), this, TQ_SLOT(fixedSizeUnitActivated(int))); + connect(mRbPercentSize, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(rbPercentSizeToggled(bool))); + connect(mRbFixedSize, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(rbFixedSizeToggled(bool))); + connect(mLimitReachedAction, TQ_SIGNAL(activated(int)), this, TQ_SLOT(setDirty())); inhibitChangedSignal = true; load(); @@ -87,7 +87,7 @@ void KTrashPropsWidget::setupGui() mountPoints->insertItem(folderPixmap, util.mountPoint(), it.key()); } mountPoints->setCurrentItem(0); - connect(mountPoints, TQT_SIGNAL(highlighted(int)), TQT_SLOT(trashChanged(int))); + connect(mountPoints, TQ_SIGNAL(highlighted(int)), TQ_SLOT(trashChanged(int))); } mCurrentTrash = map[0]; diff --git a/tdeioslave/trash/ktrashpropswidget.h b/tdeioslave/trash/ktrashpropswidget.h index 8cebfcae4..ac131039b 100644 --- a/tdeioslave/trash/ktrashpropswidget.h +++ b/tdeioslave/trash/ktrashpropswidget.h @@ -32,7 +32,7 @@ class TrashImpl; class KTrashPropsWidget : public TQWidget { - Q_OBJECT + TQ_OBJECT public: KTrashPropsWidget(TQWidget *parent=0, const char *name=0); diff --git a/tdeioslave/trash/tdefile-plugin/RETURNED_ITEMS b/tdeioslave/trash/tdefile-plugin/RETURNED_ITEMS index f4e10f262..7ada25041 100644 --- a/tdeioslave/trash/tdefile-plugin/RETURNED_ITEMS +++ b/tdeioslave/trash/tdefile-plugin/RETURNED_ITEMS @@ -1,4 +1,4 @@ tdefile_trash =========== -QString OriginalPath +TQString OriginalPath DateTime DateOfDeletion diff --git a/tdeioslave/trash/tdefile-plugin/tdefile_trash.h b/tdeioslave/trash/tdefile-plugin/tdefile_trash.h index fbd6c9e3d..afcbba1f1 100644 --- a/tdeioslave/trash/tdefile-plugin/tdefile_trash.h +++ b/tdeioslave/trash/tdefile-plugin/tdefile_trash.h @@ -28,7 +28,7 @@ class TQStringList; class KTrashPlugin: public KFilePlugin { - Q_OBJECT + TQ_OBJECT public: KTrashPlugin(TQObject *parent, const char *name, const TQStringList& args); diff --git a/tdeioslave/trash/tdeio_trash.cpp b/tdeioslave/trash/tdeio_trash.cpp index 90431afd5..aa1f63aa1 100644 --- a/tdeioslave/trash/tdeio_trash.cpp +++ b/tdeioslave/trash/tdeio_trash.cpp @@ -435,7 +435,7 @@ bool TrashProtocol::createUDSEntry( const TQString& physicalPath, const TQString addAtom( entry, TDEIO::UDS_MODIFICATION_TIME, buff.st_mtime ); addAtom( entry, TDEIO::UDS_ACCESS_TIME, buff.st_atime ); // ## or use it for deletion time? addAtom( entry, TDEIO::UDS_EXTRA, 0, info.origPath ); - addAtom( entry, TDEIO::UDS_EXTRA, 0, info.deletionDate.toString( Qt::ISODate ) ); + addAtom( entry, TDEIO::UDS_EXTRA, 0, info.deletionDate.toString( TQt::ISODate ) ); return true; } @@ -533,12 +533,12 @@ void TrashProtocol::get( const KURL& url ) KURL fileURL; fileURL.setPath( physicalPath ); TDEIO::Job* job = TDEIO::get( fileURL ); - connect( job, TQT_SIGNAL( data( TDEIO::Job*, const TQByteArray& ) ), - this, TQT_SLOT( slotData( TDEIO::Job*, const TQByteArray& ) ) ); - connect( job, TQT_SIGNAL( mimetype( TDEIO::Job*, const TQString& ) ), - this, TQT_SLOT( slotMimetype( TDEIO::Job*, const TQString& ) ) ); - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( jobFinished(TDEIO::Job *) ) ); + connect( job, TQ_SIGNAL( data( TDEIO::Job*, const TQByteArray& ) ), + this, TQ_SLOT( slotData( TDEIO::Job*, const TQByteArray& ) ) ); + connect( job, TQ_SIGNAL( mimetype( TDEIO::Job*, const TQString& ) ), + this, TQ_SLOT( slotMimetype( TDEIO::Job*, const TQString& ) ) ); + connect( job, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( jobFinished(TDEIO::Job *) ) ); tqApp->eventLoop()->enterLoop(); } diff --git a/tdeioslave/trash/tdeio_trash.h b/tdeioslave/trash/tdeio_trash.h index 1f19927ca..5d16ce93a 100644 --- a/tdeioslave/trash/tdeio_trash.h +++ b/tdeioslave/trash/tdeio_trash.h @@ -30,7 +30,7 @@ typedef TrashImpl::TrashedFileInfoList TrashedFileInfoList; class TrashProtocol : public TQObject, public TDEIO::SlaveBase { - Q_OBJECT + TQ_OBJECT public: TrashProtocol( const TQCString& protocol, const TQCString &pool, const TQCString &app); virtual ~TrashProtocol(); diff --git a/tdeioslave/trash/testtrash.cpp b/tdeioslave/trash/testtrash.cpp index 60fe2d1a6..4a1ca12f8 100644 --- a/tdeioslave/trash/testtrash.cpp +++ b/tdeioslave/trash/testtrash.cpp @@ -1094,8 +1094,8 @@ void TestTrash::listRootDir() m_entryCount = 0; m_listResult.clear(); TDEIO::ListJob* job = TDEIO::listDir( "trash:/" ); - connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ), - TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) ); + connect( job, TQ_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ), + TQ_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) ); bool ok = TDEIO::NetAccess::synchronousRun( job, 0 ); assert( ok ); kdDebug() << "listDir done - m_entryCount=" << m_entryCount << endl; @@ -1111,8 +1111,8 @@ void TestTrash::listRecursiveRootDir() m_entryCount = 0; m_listResult.clear(); TDEIO::ListJob* job = TDEIO::listRecursive( "trash:/" ); - connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ), - TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) ); + connect( job, TQ_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ), + TQ_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) ); bool ok = TDEIO::NetAccess::synchronousRun( job, 0 ); assert( ok ); kdDebug() << "listDir done - m_entryCount=" << m_entryCount << endl; @@ -1128,8 +1128,8 @@ void TestTrash::listSubDir() m_entryCount = 0; m_listResult.clear(); TDEIO::ListJob* job = TDEIO::listDir( "trash:/0-trashDirFromHome" ); - connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ), - TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) ); + connect( job, TQ_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ), + TQ_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) ); bool ok = TDEIO::NetAccess::synchronousRun( job, 0 ); assert( ok ); kdDebug() << "listDir done - m_entryCount=" << m_entryCount << endl; diff --git a/tdeioslave/trash/testtrash.h b/tdeioslave/trash/testtrash.h index e87b9c3a0..1b46e3551 100644 --- a/tdeioslave/trash/testtrash.h +++ b/tdeioslave/trash/testtrash.h @@ -22,9 +22,9 @@ #include <tqobject.h> -class TestTrash : public QObject +class TestTrash : public TQObject { - Q_OBJECT + TQ_OBJECT public: TestTrash() {} diff --git a/tdeioslave/trash/trashimpl.cpp b/tdeioslave/trash/trashimpl.cpp index c2fc53352..8c062256c 100644 --- a/tdeioslave/trash/trashimpl.cpp +++ b/tdeioslave/trash/trashimpl.cpp @@ -130,7 +130,7 @@ bool TrashImpl::init() return false; // Check the trash directory and its info and files subdirs - // see also kdesktop/init.cc for first time initialization + // see also kdesktop/init.cpp for first time initialization m_initStatus = InitError; // $XDG_DATA_HOME/Trash, i.e. ~/.local/share/Trash by default. const TQString xdgDataDir = TDEGlobal::dirs()->localxdgdatadir(); @@ -263,7 +263,7 @@ bool TrashImpl::createInfo( const TQString& origPath, int& trashId, TQString& fi info += KURL::encode_string( makeRelativePath( topDirectoryPath( trashId ), origPath ), m_mibEnum ).latin1(); info += "\n"; info += "DeletionDate="; - info += TQDateTime::currentDateTime().toString( Qt::ISODate ).latin1(); + info += TQDateTime::currentDateTime().toString( TQt::ISODate ).latin1(); info += "\n"; size_t sz = info.size() - 1; // avoid trailing 0 from QCString @@ -374,8 +374,8 @@ bool TrashImpl::move( const TQString& src, const TQString& dest ) #ifdef TDEIO_COPYJOB_HAS_SETINTERACTIVE job->setInteractive( false ); #endif - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( jobFinished(TDEIO::Job *) ) ); + connect( job, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( jobFinished(TDEIO::Job *) ) ); tqApp->eventLoop()->enterLoop(); return m_lastErrorCode == 0; @@ -424,8 +424,8 @@ bool TrashImpl::copy( const TQString& src, const TQString& dest ) #ifdef TDEIO_COPYJOB_HAS_SETINTERACTIVE job->setInteractive( false ); #endif - connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ), - this, TQT_SLOT( jobFinished( TDEIO::Job* ) ) ); + connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), + this, TQ_SLOT( jobFinished( TDEIO::Job* ) ) ); tqApp->eventLoop()->enterLoop(); return m_lastErrorCode == 0; @@ -513,15 +513,15 @@ bool TrashImpl::synchronousDel( const TQString& path, bool setLastErrorCode, boo KFileItemList fileItemList; fileItemList.append( &fileItem ); TDEIO::ChmodJob* chmodJob = TDEIO::chmod( fileItemList, 0200, 0200, TQString::null, TQString::null, true /*recursive*/, false /*showProgressInfo*/ ); - connect( chmodJob, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( jobFinished(TDEIO::Job *) ) ); + connect( chmodJob, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( jobFinished(TDEIO::Job *) ) ); tqApp->eventLoop()->enterLoop(); } kdDebug() << k_funcinfo << "deleting " << url << endl; TDEIO::DeleteJob *job = TDEIO::del( url, false, false ); - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( jobFinished(TDEIO::Job *) ) ); + connect( job, TQ_SIGNAL( result(TDEIO::Job *) ), + this, TQ_SLOT( jobFinished(TDEIO::Job *) ) ); tqApp->eventLoop()->enterLoop(); bool ok = m_lastErrorCode == 0; if ( !setLastErrorCode ) { @@ -637,7 +637,7 @@ bool TrashImpl::readInfoFile( const TQString& infoPath, TrashedFileInfo& info, i } TQString line = cfg.readEntry( "DeletionDate" ); if ( !line.isEmpty() ) { - info.deletionDate = TQT_TQDATETIME_OBJECT(TQDateTime::fromString( line, Qt::ISODate )); + info.deletionDate = TQDateTime::fromString( line, TQt::ISODate ); } return true; } diff --git a/tdeioslave/trash/trashimpl.h b/tdeioslave/trash/trashimpl.h index 571bbd353..90032762d 100644 --- a/tdeioslave/trash/trashimpl.h +++ b/tdeioslave/trash/trashimpl.h @@ -33,7 +33,7 @@ */ class TrashImpl : public TQObject { - Q_OBJECT + TQ_OBJECT public: TrashImpl(); |