00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <unistd.h>
00023 #include <stdlib.h>
00024 #include <sys/stat.h>
00025
00026 #include <qfile.h>
00027
00028 #include <kapplication.h>
00029 #include <kstandarddirs.h>
00030 #include <kdebug.h>
00031 #include <kmessagebox.h>
00032 #include <kio/job.h>
00033 #include <krun.h>
00034 #include <kio/netaccess.h>
00035 #include <kprocess.h>
00036 #include <kservice.h>
00037 #include <klocale.h>
00038 #include <kcmdlineargs.h>
00039 #include <kaboutdata.h>
00040 #include <kstartupinfo.h>
00041 #include <kshell.h>
00042
00043
00044 #include "main.h"
00045
00046
00047 static const char description[] =
00048 I18N_NOOP("KIO Exec - Opens remote files, watches modifications, asks for upload");
00049
00050 static const char version[] = "v0.0.2";
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 slotRunApp();
00129
00130 counter = 0;
00131 if ( counter == expectedCounter )
00132 slotResult( 0L );
00133 }
00134
00135 void KIOExec::slotResult( KIO::Job * job )
00136 {
00137 if (job && job->error())
00138 {
00139
00140
00141 if ( (job->error() != KIO::ERR_USER_CANCELED) )
00142 KMessageBox::error( 0L, job->errorString() );
00143
00144 QString path = static_cast<KIO::FileCopyJob*>(job)->destURL().path();
00145
00146 QValueList<fileInfo>::Iterator it = fileList.begin();
00147 for(;it != fileList.end(); ++it)
00148 {
00149 if ((*it).path == path)
00150 break;
00151 }
00152
00153 if ( it != fileList.end() )
00154 fileList.remove( it );
00155 else
00156 kdDebug() << static_cast<KIO::FileCopyJob*>(job)->destURL().path() << " not found in list" << endl;
00157 }
00158
00159 counter++;
00160
00161 if ( counter < expectedCounter )
00162 return;
00163
00164 kdDebug() << "All files downloaded, will call slotRunApp shortly" << endl;
00165
00166 QTimer::singleShot( 0, this, SLOT( slotRunApp() ) );
00167
00168 jobList->clear();
00169 }
00170
00171 void KIOExec::slotRunApp()
00172 {
00173 if ( fileList.isEmpty() ) {
00174 kdDebug() << k_funcinfo << "No files downloaded -> exiting" << endl;
00175 exit(1);
00176 }
00177
00178 KService service("dummy", command, QString::null);
00179
00180 KURL::List list;
00181
00182 QValueList<fileInfo>::Iterator it = fileList.begin();
00183 for ( ; it != fileList.end() ; ++it )
00184 {
00185 struct stat buff;
00186 (*it).time = stat( QFile::encodeName((*it).path), &buff ) ? 0 : buff.st_mtime;
00187 KURL url;
00188 url.setPath((*it).path);
00189 list << url;
00190 }
00191
00192 QStringList params = KRun::processDesktopExec(service, list, false );
00193
00194 kdDebug() << "EXEC " << KShell::joinArgs( params ) << endl;
00195
00196
00197 KStartupInfoId id;
00198 id.initId( kapp->startupId());
00199 id.setupStartupEnv();
00200
00201 KProcess proc;
00202 proc << params;
00203 proc.start( KProcess::Block );
00204
00205 KStartupInfo::resetStartupEnv();
00206
00207 kdDebug() << "EXEC done" << endl;
00208
00209
00210 it = fileList.begin();
00211 for( ;it != fileList.end(); ++it )
00212 {
00213 struct stat buff;
00214 QString src = (*it).path;
00215 KURL dest = (*it).url;
00216 if ( (stat( QFile::encodeName(src), &buff ) == 0) &&
00217 ((*it).time != buff.st_mtime) )
00218 {
00219 if ( tempfiles )
00220 {
00221 if ( KMessageBox::questionYesNo( 0L,
00222 i18n( "The supposedly temporary file\n%1\nhas been modified.\nDo you still want to delete it?" ).arg(dest.prettyURL()),
00223 i18n( "File Changed" ) ) != KMessageBox::Yes )
00224 continue;
00225 }
00226 else
00227 {
00228 if ( KMessageBox::questionYesNo( 0L,
00229 i18n( "The file\n%1\nhas been modified.\nDo you want to upload the changes?" ).arg(dest.prettyURL()),
00230 i18n( "File Changed" ) ) == KMessageBox::Yes )
00231 {
00232 kdDebug() << QString("src='%1' dest='%2'").arg(src).arg(dest.url()).ascii() << endl;
00233
00234 if ( !KIO::NetAccess::upload( src, dest, 0 ) )
00235 {
00236 KMessageBox::error( 0L, KIO::NetAccess::lastErrorString() );
00237 continue;
00238 }
00239 }
00240 }
00241 }
00242 else
00243 {
00244
00245 if (!tempfiles && dest.isLocalFile())
00246 continue;
00247 }
00248 unlink( QFile::encodeName(src) );
00249 }
00250
00251
00252 exit(0);
00253 }
00254
00255 int main( int argc, char **argv )
00256 {
00257 KAboutData aboutData( "kioexec", I18N_NOOP("KIOExec"),
00258 version, description, KAboutData::License_GPL,
00259 "(c) 1998-2000,2003 The KFM/Konqueror Developers");
00260 aboutData.addAuthor("David Faure",0, "faure@kde.org");
00261 aboutData.addAuthor("Stephen Kulow",0, "coolo@kde.org");
00262 aboutData.addAuthor("Bernhard Rosenkraenzer",0, "bero@arklinux.org");
00263 aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org");
00264 aboutData.addAuthor("Oswald Buddenhagen",0, "ossi@kde.org");
00265
00266 KCmdLineArgs::init( argc, argv, &aboutData );
00267 KCmdLineArgs::addCmdLineOptions( options );
00268
00269 KApplication app;
00270
00271 KIOExec exec;
00272
00273 kdDebug() << "Constructor returned..." << endl;
00274 return app.exec();
00275 }
00276
00277 #include "main.moc"