00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023 #include <unistd.h>
00024 #include <stdlib.h>
00025 #include <sys/stat.h>
00026
00027 #include <qfile.h>
00028
00029 #include <kapplication.h>
00030 #include <kstandarddirs.h>
00031 #include <kdebug.h>
00032 #include <kmessagebox.h>
00033 #include <kio/job.h>
00034 #include <krun.h>
00035 #include <kio/netaccess.h>
00036 #include <kprocess.h>
00037 #include <kservice.h>
00038 #include <klocale.h>
00039 #include <kcmdlineargs.h>
00040 #include <kaboutdata.h>
00041 #include <kstartupinfo.h>
00042 #include <kshell.h>
00043 #include <kde_file.h>
00044
00045
00046 #include "main.h"
00047
00048
00049 static const char description[] =
00050 I18N_NOOP("KIO Exec - Opens remote files, watches modifications, asks for upload");
00051
00052 static KCmdLineOptions options[] =
00053 {
00054 { "tempfiles", I18N_NOOP("Treat URLs as local files and delete them afterwards"), 0 },
00055 { "suggestedfilename <file name>", I18N_NOOP("Suggested file name for the downloaded file"), 0 },
00056 { "+command", I18N_NOOP("Command to execute"), 0 },
00057 { "+[URLs]", I18N_NOOP("URL(s) or local file(s) used for 'command'"), 0 },
00058 KCmdLineLastOption
00059 };
00060
00061
00062 int jobCounter = 0;
00063
00064 QPtrList<KIO::Job>* jobList = 0L;
00065
00066 KIOExec::KIOExec()
00067 {
00068 jobList = new QPtrList<KIO::Job>;
00069 jobList->setAutoDelete( false );
00070
00071 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00072 if (args->count() < 1)
00073 KCmdLineArgs::usage(i18n("'command' expected.\n"));
00074
00075 tempfiles = args->isSet("tempfiles");
00076 if ( args->isSet( "suggestedfilename" ) )
00077 suggestedFileName = QString::fromLocal8Bit( args->getOption( "suggestedfilename" ) );
00078 expectedCounter = 0;
00079 command = args->arg(0);
00080 kdDebug() << "command=" << command << endl;
00081
00082 for ( int i = 1; i < args->count(); i++ )
00083 {
00084 KURL url = args->url(i);
00085
00086 url = KIO::NetAccess::mostLocalURL( url, 0 );
00087
00088
00089
00090
00091 if ( url.isLocalFile() )
00092 {
00093 fileInfo file;
00094 file.path = url.path();
00095 file.url = url;
00096 fileList.append(file);
00097 }
00098
00099 else
00100 {
00101 if ( !url.isValid() )
00102 KMessageBox::error( 0L, i18n( "The URL %1\nis malformed" ).arg( url.url() ) );
00103 else if ( tempfiles )
00104 KMessageBox::error( 0L, i18n( "Remote URL %1\nnot allowed with --tempfiles switch" ).arg( url.url() ) );
00105 else
00106
00107 {
00108 QString fileName = KIO::encodeFileName( url.fileName() );
00109 if ( !suggestedFileName.isEmpty() )
00110 fileName = suggestedFileName;
00111
00112
00113
00114 QString tmp = KGlobal::dirs()->saveLocation( "cache", "krun/" ) +
00115 QString("%1.%2.%3").arg(getpid()).arg(jobCounter++).arg(fileName);
00116 fileInfo file;
00117 file.path = tmp;
00118 file.url = url;
00119 fileList.append(file);
00120
00121 expectedCounter++;
00122 KURL dest;
00123 dest.setPath( tmp );
00124 kdDebug() << "Copying " << url.prettyURL() << " to " << dest << endl;
00125 KIO::Job *job = KIO::file_copy( url, dest );
00126 jobList->append( job );
00127
00128 connect( job, SIGNAL( result( KIO::Job * ) ), SLOT( slotResult( KIO::Job * ) ) );
00129 }
00130 }
00131 }
00132 args->clear();
00133
00134 if ( tempfiles ) {
00135
00136 QTimer::singleShot( 0, this, SLOT( slotRunApp() ) );
00137
00138 return;
00139 }
00140
00141 counter = 0;
00142 if ( counter == expectedCounter )
00143 slotResult( 0L );
00144 }
00145
00146 void KIOExec::slotResult( KIO::Job * job )
00147 {
00148 if (job && job->error())
00149 {
00150
00151
00152 if ( (job->error() != KIO::ERR_USER_CANCELED) )
00153 KMessageBox::error( 0L, job->errorString() );
00154
00155 QString path = static_cast<KIO::FileCopyJob*>(job)->destURL().path();
00156
00157 QValueList<fileInfo>::Iterator it = fileList.begin();
00158 for(;it != fileList.end(); ++it)
00159 {
00160 if ((*it).path == path)
00161 break;
00162 }
00163
00164 if ( it != fileList.end() )
00165 fileList.remove( it );
00166 else
00167 kdDebug() << static_cast<KIO::FileCopyJob*>(job)->destURL().path() << " not found in list" << endl;
00168 }
00169
00170 counter++;
00171
00172 if ( counter < expectedCounter )
00173 return;
00174
00175 kdDebug() << "All files downloaded, will call slotRunApp shortly" << endl;
00176
00177 QTimer::singleShot( 0, this, SLOT( slotRunApp() ) );
00178
00179 jobList->clear();
00180 }
00181
00182 void KIOExec::slotRunApp()
00183 {
00184 if ( fileList.isEmpty() ) {
00185 kdDebug() << k_funcinfo << "No files downloaded -> exiting" << endl;
00186 exit(1);
00187 }
00188
00189 KService service("dummy", command, QString::null);
00190
00191 KURL::List list;
00192
00193 QValueList<fileInfo>::Iterator it = fileList.begin();
00194 for ( ; it != fileList.end() ; ++it )
00195 {
00196 KDE_struct_stat buff;
00197 (*it).time = KDE_stat( QFile::encodeName((*it).path), &buff ) ? 0 : buff.st_mtime;
00198 KURL url;
00199 url.setPath((*it).path);
00200 list << url;
00201 }
00202
00203 QStringList params = KRun::processDesktopExec(service, list, false );
00204
00205 kdDebug() << "EXEC " << KShell::joinArgs( params ) << endl;
00206
00207 #ifdef Q_WS_X11
00208
00209 KStartupInfoId id;
00210 id.initId( kapp->startupId());
00211 id.setupStartupEnv();
00212 #endif
00213
00214 KProcess proc;
00215 proc << params;
00216 proc.start( KProcess::Block );
00217
00218 #ifdef Q_WS_X11
00219 KStartupInfo::resetStartupEnv();
00220 #endif
00221
00222 kdDebug() << "EXEC done" << endl;
00223
00224
00225 it = fileList.begin();
00226 for( ;it != fileList.end(); ++it )
00227 {
00228 KDE_struct_stat buff;
00229 QString src = (*it).path;
00230 KURL dest = (*it).url;
00231 if ( (KDE_stat( QFile::encodeName(src), &buff ) == 0) &&
00232 ((*it).time != buff.st_mtime) )
00233 {
00234 if ( tempfiles )
00235 {
00236 if ( KMessageBox::questionYesNo( 0L,
00237 i18n( "The supposedly temporary file\n%1\nhas been modified.\nDo you still want to delete it?" ).arg(dest.prettyURL()),
00238 i18n( "File Changed" ), KStdGuiItem::del(), i18n("Do Not Delete") ) != KMessageBox::Yes )
00239 continue;
00240 }
00241 else if ( ! dest.isLocalFile() )
00242 {
00243 if ( KMessageBox::questionYesNo( 0L,
00244 i18n( "The file\n%1\nhas been modified.\nDo you want to upload the changes?" ).arg(dest.prettyURL()),
00245 i18n( "File Changed" ), i18n("Upload"), i18n("Do Not Upload") ) == KMessageBox::Yes )
00246 {
00247 kdDebug() << QString("src='%1' dest='%2'").arg(src).arg(dest.url()).ascii() << endl;
00248
00249 if ( !KIO::NetAccess::upload( src, dest, 0 ) )
00250 {
00251 KMessageBox::error( 0L, KIO::NetAccess::lastErrorString() );
00252 continue;
00253 }
00254 }
00255 }
00256 }
00257
00258 if ( !dest.isLocalFile() || tempfiles ) {
00259
00260
00261 kdDebug() << "sleeping..." << endl;
00262 sleep(180);
00263 kdDebug() << "about to delete " << src << endl;
00264 unlink( QFile::encodeName(src) );
00265 }
00266 }
00267
00268
00269 exit(0);
00270 }
00271
00272 int main( int argc, char **argv )
00273 {
00274 KAboutData aboutData( "kioexec", I18N_NOOP("KIOExec"),
00275 VERSION, description, KAboutData::License_GPL,
00276 "(c) 1998-2000,2003 The KFM/Konqueror Developers");
00277 aboutData.addAuthor("David Faure",0, "faure@kde.org");
00278 aboutData.addAuthor("Stephan Kulow",0, "coolo@kde.org");
00279 aboutData.addAuthor("Bernhard Rosenkraenzer",0, "bero@arklinux.org");
00280 aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org");
00281 aboutData.addAuthor("Oswald Buddenhagen",0, "ossi@kde.org");
00282
00283 KCmdLineArgs::init( argc, argv, &aboutData );
00284 KCmdLineArgs::addCmdLineOptions( options );
00285
00286 KApplication app;
00287
00288 KIOExec exec;
00289
00290 kdDebug() << "Constructor returned..." << endl;
00291 return app.exec();
00292 }
00293
00294 #include "main.moc"