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