kio Library API Documentation

main.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003    Copyright (C)       2000 David Faure <faure@kde.org>
00004    Copyright (C)       2001 Waldo Bastian <bastian@kde.org>
00005 
00006    This program is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; see the file COPYING.  If not, write to
00018    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.
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 ); // jobs autodelete themselves
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         //kdDebug() << "url=" << url.url() << " filename=" << url.fileName() << endl;
00084         // A local file, not an URL ?
00085         // => It is not encoded and not shell escaped, too.
00086         if ( url.isLocalFile() )
00087         {
00088             fileInfo file;
00089             file.path = url.path();
00090             file.url = url;
00091             fileList.append(file);
00092         }
00093         // It is an URL
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             // We must fetch the file
00102             {
00103                 QString fileName = KIO::encodeFileName( url.fileName() );
00104                 // Build the destination filename, in ~/.kde/cache-*/krun/
00105                 // Unlike KDE-1.1, we put the filename at the end so that the extension is kept
00106                 // (Some programs rely on it)
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(); // does not return
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         // That error dialog would be queued, i.e. not immediate...
00140         //job->showErrorDialog();
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     // We know we can run the app now - but let's finish the job properly first.
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     // Store modification times
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 /*no shell*/);
00193 
00194     kdDebug() << "EXEC " << KShell::joinArgs( params ) << endl;
00195 
00196     // propagate the startup indentification to the started process
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     // Test whether one of the files changed
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; // don't delete the temp file
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                     // Do it the synchronous way.
00234                     if ( !KIO::NetAccess::upload( src, dest, 0 ) )
00235                     {
00236                         KMessageBox::error( 0L, KIO::NetAccess::lastErrorString() );
00237                         continue; // don't delete the temp file
00238                     }
00239                 }
00240             }
00241         }
00242         else
00243         {
00244             // don't upload (and delete!) local files
00245             if (!tempfiles && dest.isLocalFile())
00246                 continue;
00247         }
00248         unlink( QFile::encodeName(src) );
00249     }
00250 
00251     //kapp->quit(); not efficient enough
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"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Aug 4 05:25:37 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003