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