diff options
Diffstat (limited to 'tdeio/tdeioexec')
-rw-r--r-- | tdeio/tdeioexec/CMakeLists.txt | 42 | ||||
-rw-r--r-- | tdeio/tdeioexec/Makefile.am | 19 | ||||
-rw-r--r-- | tdeio/tdeioexec/README | 26 | ||||
-rw-r--r-- | tdeio/tdeioexec/main.cpp | 294 | ||||
-rw-r--r-- | tdeio/tdeioexec/main.h | 35 |
5 files changed, 416 insertions, 0 deletions
diff --git a/tdeio/tdeioexec/CMakeLists.txt b/tdeio/tdeioexec/CMakeLists.txt new file mode 100644 index 000000000..b0cdf0b52 --- /dev/null +++ b/tdeio/tdeioexec/CMakeLists.txt @@ -0,0 +1,42 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeui + ${CMAKE_SOURCE_DIR}/tdeio + ${CMAKE_SOURCE_DIR}/tdeio/tdeio +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### tdeioexec ################################### + +set( target tdeioexec ) + +set( ${target}_SRCS + main.cpp +) + +tde_add_executable( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeio-shared + DESTINATION ${BIN_INSTALL_DIR} +) + +tde_install_symlink( ${target} ${BIN_INSTALL_DIR}/kfmexec ) diff --git a/tdeio/tdeioexec/Makefile.am b/tdeio/tdeioexec/Makefile.am new file mode 100644 index 000000000..2879342ff --- /dev/null +++ b/tdeio/tdeioexec/Makefile.am @@ -0,0 +1,19 @@ +AM_CPPFLAGS = $(all_includes) + +bin_PROGRAMS = tdeioexec + +tdeioexec_SOURCES = main.cpp +tdeioexec_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor +tdeioexec_LDADD = $(LIB_KIO) + +noinst_HEADERS = main.h +METASOURCES = AUTO + +messages: + $(XGETTEXT) $(tdeioexec_SOURCES) -o $(podir)/tdeioexec.pot + +install-exec-local: + @rm -f $(DESTDIR)$(bindir)/kfmexec + @$(LN_S) tdeioexec $(DESTDIR)$(bindir)/kfmexec + +include $(top_srcdir)/admin/Doxyfile.am diff --git a/tdeio/tdeioexec/README b/tdeio/tdeioexec/README new file mode 100644 index 000000000..daaa38bdb --- /dev/null +++ b/tdeio/tdeioexec/README @@ -0,0 +1,26 @@ +kfmexec is launched when the user wants to open a remote file with +an application that only supports local files. + +For this it does the following: +- downloads a remote file to a temp location +- starts a 'local' application with that temp file as argument +- wait fors application to be exited +- if the modification time of the file is different from the original one, +(because the file was modified) then it offers re-uploading the modified version. +This is how you offer network transparency to apps that don't have it. + +BUT: with KUniqueApplication, this breaks, because the app returns at once, +so we have no way to know when the user finished editing the file... + +Conclusion: if the application has network transparency built-in, it should +put "%u" in its desktop file - and kfmexec isn't used -. If it doesn't, either +it's a TDEApplication and kfmexec does its job, or it's a KUniqueApplication +and... kfmexec can't see modifications to the file. Be warned. + +From Waldo: "The program doesn't return _at once_. It returns +after "newInstance()" returns. So if you open the file there it will still work. +(Or rename it)" + +David Faure <faure@kde.org> +20-May-2000 + diff --git a/tdeio/tdeioexec/main.cpp b/tdeio/tdeioexec/main.cpp new file mode 100644 index 000000000..9f7bd9faa --- /dev/null +++ b/tdeio/tdeioexec/main.cpp @@ -0,0 +1,294 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> + Copyright (C) 2000 David Faure <faure@kde.org> + Copyright (C) 2001 Waldo Bastian <bastian@kde.org> + + 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. + + This program 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <config.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <tqfile.h> + +#include <kapplication.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kmessagebox.h> +#include <tdeio/job.h> +#include <krun.h> +#include <tdeio/netaccess.h> +#include <kprocess.h> +#include <kservice.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <kstartupinfo.h> +#include <kshell.h> +#include <kde_file.h> + + +#include "main.h" + + +static const char description[] = + I18N_NOOP("KIO Exec - Opens remote files, watches modifications, asks for upload"); + +static KCmdLineOptions options[] = +{ + { "tempfiles", I18N_NOOP("Treat URLs as local files and delete them afterwards"), 0 }, + { "suggestedfilename <file name>", I18N_NOOP("Suggested file name for the downloaded file"), 0 }, + { "+command", I18N_NOOP("Command to execute"), 0 }, + { "+[URLs]", I18N_NOOP("URL(s) or local file(s) used for 'command'"), 0 }, + KCmdLineLastOption +}; + + +int jobCounter = 0; + +TQPtrList<TDEIO::Job>* jobList = 0L; + +KIOExec::KIOExec() +{ + jobList = new TQPtrList<TDEIO::Job>; + jobList->setAutoDelete( false ); // jobs autodelete themselves + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + if (args->count() < 1) + TDECmdLineArgs::usage(i18n("'command' expected.\n")); + + tempfiles = args->isSet("tempfiles"); + if ( args->isSet( "suggestedfilename" ) ) + suggestedFileName = TQString::fromLocal8Bit( args->getOption( "suggestedfilename" ) ); + expectedCounter = 0; + command = args->arg(0); + kdDebug() << "command=" << command << endl; + + for ( int i = 1; i < args->count(); i++ ) + { + KURL url = args->url(i); + // we need to map system:/ etc to make sure we get this right + url = TDEIO::NetAccess::mostLocalURL( url, 0 ); + + //kdDebug() << "url=" << url.url() << " filename=" << url.fileName() << endl; + // A local file, not an URL ? + // => It is not encoded and not shell escaped, too. + if ( url.isLocalFile() ) + { + fileInfo file; + file.path = url.path(); + file.url = url; + fileList.append(file); + } + // It is an URL + else + { + if ( !url.isValid() ) + KMessageBox::error( 0L, i18n( "The URL %1\nis malformed" ).arg( url.url() ) ); + else if ( tempfiles ) + KMessageBox::error( 0L, i18n( "Remote URL %1\nnot allowed with --tempfiles switch" ).arg( url.url() ) ); + else + // We must fetch the file + { + TQString fileName = TDEIO::encodeFileName( url.fileName() ); + if ( !suggestedFileName.isEmpty() ) + fileName = suggestedFileName; + // Build the destination filename, in ~/.trinity/cache-*/krun/ + // Unlike KDE-1.1, we put the filename at the end so that the extension is kept + // (Some programs rely on it) + TQString tmp = TDEGlobal::dirs()->saveLocation( "cache", "krun/" ) + + TQString("%1.%2.%3").arg(getpid()).arg(jobCounter++).arg(fileName); + fileInfo file; + file.path = tmp; + file.url = url; + fileList.append(file); + + expectedCounter++; + KURL dest; + dest.setPath( tmp ); + kdDebug() << "Copying " << url.prettyURL() << " to " << dest << endl; + TDEIO::Job *job = TDEIO::file_copy( url, dest ); + jobList->append( job ); + + connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), TQT_SLOT( slotResult( TDEIO::Job * ) ) ); + } + } + } + args->clear(); + + if ( tempfiles ) { + // #113991 + TQTimer::singleShot( 0, this, TQT_SLOT( slotRunApp() ) ); + //slotRunApp(); // does not return + return; + } + + counter = 0; + if ( counter == expectedCounter ) + slotResult( 0L ); +} + +void KIOExec::slotResult( TDEIO::Job * job ) +{ + if (job && job->error()) + { + // That error dialog would be queued, i.e. not immediate... + //job->showErrorDialog(); + if ( (job->error() != TDEIO::ERR_USER_CANCELED) ) + KMessageBox::error( 0L, job->errorString() ); + + TQString path = static_cast<TDEIO::FileCopyJob*>(job)->destURL().path(); + + TQValueList<fileInfo>::Iterator it = fileList.begin(); + for(;it != fileList.end(); ++it) + { + if ((*it).path == path) + break; + } + + if ( it != fileList.end() ) + fileList.remove( it ); + else + kdDebug() << static_cast<TDEIO::FileCopyJob*>(job)->destURL().path() << " not found in list" << endl; + } + + counter++; + + if ( counter < expectedCounter ) + return; + + kdDebug() << "All files downloaded, will call slotRunApp shortly" << endl; + // We know we can run the app now - but let's finish the job properly first. + TQTimer::singleShot( 0, this, TQT_SLOT( slotRunApp() ) ); + + jobList->clear(); +} + +void KIOExec::slotRunApp() +{ + if ( fileList.isEmpty() ) { + kdDebug() << k_funcinfo << "No files downloaded -> exiting" << endl; + exit(1); + } + + KService service("dummy", command, TQString::null); + + KURL::List list; + // Store modification times + TQValueList<fileInfo>::Iterator it = fileList.begin(); + for ( ; it != fileList.end() ; ++it ) + { + KDE_struct_stat buff; + (*it).time = KDE_stat( TQFile::encodeName((*it).path), &buff ) ? 0 : buff.st_mtime; + KURL url; + url.setPath((*it).path); + list << url; + } + + TQStringList params = KRun::processDesktopExec(service, list, false /*no shell*/); + + kdDebug() << "EXEC " << KShell::joinArgs( params ) << endl; + +#ifdef Q_WS_X11 + // propagate the startup indentification to the started process + KStartupInfoId id; + id.initId( kapp->startupId()); + id.setupStartupEnv(); +#endif + + TDEProcess proc; + proc << params; + proc.start( TDEProcess::Block ); + +#ifdef Q_WS_X11 + KStartupInfo::resetStartupEnv(); +#endif + + kdDebug() << "EXEC done" << endl; + + // Test whether one of the files changed + it = fileList.begin(); + for( ;it != fileList.end(); ++it ) + { + KDE_struct_stat buff; + TQString src = (*it).path; + KURL dest = (*it).url; + if ( (KDE_stat( TQFile::encodeName(src), &buff ) == 0) && + ((*it).time != buff.st_mtime) ) + { + if ( tempfiles ) + { + if ( KMessageBox::questionYesNo( 0L, + i18n( "The supposedly temporary file\n%1\nhas been modified.\nDo you still want to delete it?" ).arg(dest.prettyURL()), + i18n( "File Changed" ), KStdGuiItem::del(), i18n("Do Not Delete") ) != KMessageBox::Yes ) + continue; // don't delete the temp file + } + else if ( ! dest.isLocalFile() ) // no upload when it's already a local file + { + if ( KMessageBox::questionYesNo( 0L, + i18n( "The file\n%1\nhas been modified.\nDo you want to upload the changes?" ).arg(dest.prettyURL()), + i18n( "File Changed" ), i18n("Upload"), i18n("Do Not Upload") ) == KMessageBox::Yes ) + { + kdDebug() << TQString(TQString("src='%1' dest='%2'").arg(src).arg(dest.url())).ascii() << endl; + // Do it the synchronous way. + if ( !TDEIO::NetAccess::upload( src, dest, 0 ) ) + { + KMessageBox::error( 0L, TDEIO::NetAccess::lastErrorString() ); + continue; // don't delete the temp file + } + } + } + } + + if ( !dest.isLocalFile() || tempfiles ) { + // Wait for a reasonable time so that even if the application forks on startup (like OOo or amarok) + // it will have time to start up and read the file before it gets deleted. #130709. + kdDebug() << "sleeping..." << endl; + sleep(180); // 3 mn + kdDebug() << "about to delete " << src << endl; + unlink( TQFile::encodeName(src) ); + } + } + + //kapp->quit(); not efficient enough + exit(0); +} + +int main( int argc, char **argv ) +{ + TDEAboutData aboutData( "tdeioexec", I18N_NOOP("KIOExec"), + VERSION, description, TDEAboutData::License_GPL, + "(c) 1998-2000,2003 The KFM/Konqueror Developers"); + aboutData.addAuthor("David Faure",0, "faure@kde.org"); + aboutData.addAuthor("Stephan Kulow",0, "coolo@kde.org"); + aboutData.addAuthor("Bernhard Rosenkraenzer",0, "bero@arklinux.org"); + aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org"); + aboutData.addAuthor("Oswald Buddenhagen",0, "ossi@kde.org"); + + TDECmdLineArgs::init( argc, argv, &aboutData ); + TDECmdLineArgs::addCmdLineOptions( options ); + + TDEApplication app; + + KIOExec exec; + + kdDebug() << "Constructor returned..." << endl; + return app.exec(); +} + +#include "main.moc" diff --git a/tdeio/tdeioexec/main.h b/tdeio/tdeioexec/main.h new file mode 100644 index 000000000..beb6a2297 --- /dev/null +++ b/tdeio/tdeioexec/main.h @@ -0,0 +1,35 @@ +#ifndef _main_h +#define _main_h + +#include <tqobject.h> +#include <tqstring.h> +#include <tqstrlist.h> +#include <tqtimer.h> + +namespace TDEIO { class Job; } + +class KIOExec : public TQObject +{ + Q_OBJECT +public: + KIOExec(); + +public slots: + void slotResult( TDEIO::Job * ); + void slotRunApp(); + +protected: + bool tempfiles; + TQString suggestedFileName; + int counter; + int expectedCounter; + TQString command; + struct fileInfo { + TQString path; + KURL url; + int time; + }; + TQValueList<fileInfo> fileList; +}; + +#endif |