• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

netaccess.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the KDE libraries
00003     Copyright (C) 1997 Torben Weis (weis@kde.org)
00004     Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org)
00005     Copyright (C) 1999 David Faure (faure@kde.org)
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "netaccess.h"
00024 
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <signal.h>
00028 #include <unistd.h>
00029 
00030 #include <cstring>
00031 
00032 #include <QtCore/QCharRef>
00033 #include <QtGui/QApplication>
00034 #include <QtCore/QFile>
00035 #include <QtCore/QMetaClassInfo>
00036 #include <QtCore/QTextIStream>
00037 
00038 #include <kapplication.h>
00039 #include <klocale.h>
00040 #include <ktemporaryfile.h>
00041 #include <kdebug.h>
00042 #include <kurl.h>
00043 #include <kstandarddirs.h>
00044 
00045 #include "job.h"
00046 #include "copyjob.h"
00047 #include "deletejob.h"
00048 #include "jobuidelegate.h"
00049 #include "scheduler.h"
00050 
00051 namespace KIO
00052 {
00053     class NetAccessPrivate
00054     {
00055     public:
00056         NetAccessPrivate()
00057             : m_metaData(0)
00058             , bJobOK(true)
00059         {}
00060         UDSEntry m_entry;
00061         QString m_mimetype;
00062         QByteArray m_data;
00063         KUrl m_url;
00064         QMap<QString, QString> *m_metaData;
00065 
00069         bool bJobOK;
00070     };
00071 
00072 } // namespace KIO
00073 
00074 using namespace KIO;
00075 
00076 
00080 static QStringList* tmpfiles;
00081 
00082 static QString* lastErrorMsg = 0;
00083 static int lastErrorCode = 0;
00084 
00085 NetAccess::NetAccess() :
00086     d( new NetAccessPrivate )
00087 {
00088 }
00089 
00090 NetAccess::~NetAccess()
00091 {
00092     delete d;
00093 }
00094 
00095 bool NetAccess::download(const KUrl& u, QString & target, QWidget* window)
00096 {
00097   if (u.isLocalFile()) {
00098     // file protocol. We do not need the network
00099     target = u.path();
00100     bool accessible = KStandardDirs::checkAccess(target, R_OK);
00101     if(!accessible)
00102     {
00103         if(!lastErrorMsg)
00104             lastErrorMsg = new QString;
00105         *lastErrorMsg = i18n("File '%1' is not readable", target);
00106         lastErrorCode = ERR_COULD_NOT_READ;
00107     }
00108     return accessible;
00109   }
00110 
00111   if (target.isEmpty())
00112   {
00113       KTemporaryFile tmpFile;
00114       tmpFile.setAutoRemove(false);
00115       tmpFile.open();
00116       target = tmpFile.fileName();
00117       if (!tmpfiles)
00118           tmpfiles = new QStringList;
00119       tmpfiles->append(target);
00120   }
00121 
00122   NetAccess kioNet;
00123   KUrl dest;
00124   dest.setPath( target );
00125   return kioNet.filecopyInternal( u, dest, -1, KIO::Overwrite, window, false /*copy*/);
00126 }
00127 
00128 bool NetAccess::upload(const QString& src, const KUrl& target, QWidget* window)
00129 {
00130   if (target.isEmpty())
00131     return false;
00132 
00133   // If target is local... well, just copy. This can be useful
00134   // when the client code uses a temp file no matter what.
00135   // Let's make sure it's not the exact same file though
00136   if (target.isLocalFile() && target.path() == src)
00137     return true;
00138 
00139   NetAccess kioNet;
00140   KUrl s;
00141   s.setPath(src);
00142   return kioNet.filecopyInternal( s, target, -1, KIO::Overwrite, window, false /*copy*/ );
00143 }
00144 
00145 bool NetAccess::file_copy( const KUrl & src, const KUrl & target, QWidget* window )
00146 {
00147   NetAccess kioNet;
00148   return kioNet.filecopyInternal( src, target, -1, KIO::DefaultFlags,
00149                                   window, false /*copy*/ );
00150 }
00151 
00152 bool NetAccess::copy( const KUrl& src, const KUrl& target, QWidget* window )
00153 {
00154     return file_copy( src, target, window );
00155 }
00156 
00157 // bool NetAccess::file_copy( const KUrl& src, const KUrl& target, int permissions,
00158 //                            bool overwrite, bool resume, QWidget* window )
00159 // {
00160 //   NetAccess kioNet;
00161 //   return kioNet.filecopyInternal( src, target, permissions, overwrite, resume,
00162 //                                   window, false /*copy*/ );
00163 // }
00164 
00165 
00166 // bool NetAccess::file_move( const KUrl& src, const KUrl& target, int permissions,
00167 //                            bool overwrite, bool resume, QWidget* window )
00168 // {
00169 //   NetAccess kioNet;
00170 //   return kioNet.filecopyInternal( src, target, permissions, overwrite, resume,
00171 //                                   window, true /*move*/ );
00172 // }
00173 
00174 bool NetAccess::dircopy( const KUrl & src, const KUrl & target, QWidget* window )
00175 {
00176   KUrl::List srcList;
00177   srcList.append( src );
00178   return NetAccess::dircopy( srcList, target, window );
00179 }
00180 
00181 bool NetAccess::dircopy( const KUrl::List & srcList, const KUrl & target, QWidget* window )
00182 {
00183   NetAccess kioNet;
00184   return kioNet.dircopyInternal( srcList, target, window, false /*copy*/ );
00185 }
00186 
00187 bool NetAccess::move( const KUrl& src, const KUrl& target, QWidget* window )
00188 {
00189   KUrl::List srcList;
00190   srcList.append( src );
00191   NetAccess kioNet;
00192   return kioNet.dircopyInternal( srcList, target, window, true /*move*/ );
00193 }
00194 
00195 bool NetAccess::move( const KUrl::List& srcList, const KUrl& target, QWidget* window )
00196 {
00197   NetAccess kioNet;
00198   return kioNet.dircopyInternal( srcList, target, window, true /*move*/ );
00199 }
00200 
00201 bool NetAccess::exists( const KUrl & url, bool source, QWidget* window )
00202 {
00203   if ( url.isLocalFile() )
00204     return QFile::exists( url.path() );
00205   NetAccess kioNet;
00206   return kioNet.statInternal( url, 0 /*no details*/,
00207                               source ? SourceSide : DestinationSide, window );
00208 }
00209 
00210 bool NetAccess::exists( const KUrl & url, StatSide side, QWidget* window )
00211 {
00212   if ( url.isLocalFile() )
00213     return QFile::exists( url.path() );
00214   NetAccess kioNet;
00215   return kioNet.statInternal( url, 0 /*no details*/, side, window );
00216 }
00217 
00218 bool NetAccess::stat( const KUrl & url, KIO::UDSEntry & entry, QWidget* window )
00219 {
00220   NetAccess kioNet;
00221   bool ret = kioNet.statInternal( url, 2 /*all details*/, SourceSide, window );
00222   if (ret)
00223     entry = kioNet.d->m_entry;
00224   return ret;
00225 }
00226 
00227 KUrl NetAccess::mostLocalUrl(const KUrl & url, QWidget* window)
00228 {
00229   if ( url.isLocalFile() )
00230   {
00231     return url;
00232   }
00233 
00234   KIO::UDSEntry entry;
00235   if (!stat(url, entry, window))
00236   {
00237     return url;
00238   }
00239 
00240   const QString path = entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
00241   if ( !path.isEmpty() )
00242   {
00243     KUrl new_url;
00244     new_url.setPath(path);
00245     return new_url;
00246   }
00247 
00248   return url;
00249 }
00250 
00251 bool NetAccess::del( const KUrl & url, QWidget* window )
00252 {
00253   NetAccess kioNet;
00254   return kioNet.delInternal( url, window );
00255 }
00256 
00257 bool NetAccess::mkdir( const KUrl & url, QWidget* window, int permissions )
00258 {
00259   NetAccess kioNet;
00260   return kioNet.mkdirInternal( url, permissions, window );
00261 }
00262 
00263 QString NetAccess::fish_execute( const KUrl & url, const QString &command, QWidget* window )
00264 {
00265   NetAccess kioNet;
00266   return kioNet.fish_executeInternal( url, command, window );
00267 }
00268 
00269 bool NetAccess::synchronousRun( Job* job, QWidget* window, QByteArray* data,
00270                                 KUrl* finalURL, QMap<QString, QString>* metaData )
00271 {
00272   NetAccess kioNet;
00273   return kioNet.synchronousRunInternal( job, window, data, finalURL, metaData );
00274 }
00275 
00276 QString NetAccess::mimetype( const KUrl& url, QWidget* window )
00277 {
00278   NetAccess kioNet;
00279   return kioNet.mimetypeInternal( url, window );
00280 }
00281 
00282 QString NetAccess::lastErrorString()
00283 {
00284     return lastErrorMsg ? *lastErrorMsg : QString();
00285 }
00286 
00287 int NetAccess::lastError()
00288 {
00289     return lastErrorCode;
00290 }
00291 
00292 void NetAccess::removeTempFile(const QString& name)
00293 {
00294   if (!tmpfiles)
00295     return;
00296   if (tmpfiles->contains(name))
00297   {
00298     unlink(QFile::encodeName(name));
00299     tmpfiles->removeAll(name);
00300   }
00301 }
00302 
00303 bool NetAccess::filecopyInternal(const KUrl& src, const KUrl& target, int permissions,
00304                                  KIO::JobFlags flags, QWidget* window, bool move)
00305 {
00306   d->bJobOK = true; // success unless further error occurs
00307 
00308   KIO::Scheduler::checkSlaveOnHold(true);
00309   KIO::Job * job = move
00310                    ? KIO::file_move( src, target, permissions, flags )
00311                    : KIO::file_copy( src, target, permissions, flags );
00312   job->ui()->setWindow (window);
00313   connect( job, SIGNAL( result (KJob *) ),
00314            this, SLOT( slotResult (KJob *) ) );
00315 
00316   enter_loop();
00317   return d->bJobOK;
00318 }
00319 
00320 bool NetAccess::dircopyInternal(const KUrl::List& src, const KUrl& target,
00321                                 QWidget* window, bool move)
00322 {
00323   d->bJobOK = true; // success unless further error occurs
00324 
00325   KIO::Job * job = move
00326                    ? KIO::move( src, target )
00327                    : KIO::copy( src, target );
00328   job->ui()->setWindow (window);
00329   connect( job, SIGNAL( result (KJob *) ),
00330            this, SLOT( slotResult (KJob *) ) );
00331 
00332   enter_loop();
00333   return d->bJobOK;
00334 }
00335 
00336 bool NetAccess::statInternal( const KUrl & url, int details, StatSide side,
00337                               QWidget* window )
00338 {
00339   d->bJobOK = true; // success unless further error occurs
00340   KIO::JobFlags flags = url.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags;
00341   KIO::StatJob * job = KIO::stat( url, flags );
00342   job->ui()->setWindow (window);
00343   job->setDetails( details );
00344   job->setSide( side == SourceSide ? StatJob::SourceSide : StatJob::DestinationSide );
00345   connect( job, SIGNAL( result (KJob *) ),
00346            this, SLOT( slotResult (KJob *) ) );
00347   enter_loop();
00348   return d->bJobOK;
00349 }
00350 
00351 bool NetAccess::delInternal( const KUrl & url, QWidget* window )
00352 {
00353   d->bJobOK = true; // success unless further error occurs
00354   KIO::Job * job = KIO::del( url );
00355   job->ui()->setWindow (window);
00356   connect( job, SIGNAL( result (KJob *) ),
00357            this, SLOT( slotResult (KJob *) ) );
00358   enter_loop();
00359   return d->bJobOK;
00360 }
00361 
00362 bool NetAccess::mkdirInternal( const KUrl & url, int permissions,
00363                                QWidget* window )
00364 {
00365   d->bJobOK = true; // success unless further error occurs
00366   KIO::Job * job = KIO::mkdir( url, permissions );
00367   job->ui()->setWindow (window);
00368   connect( job, SIGNAL( result (KJob *) ),
00369            this, SLOT( slotResult (KJob *) ) );
00370   enter_loop();
00371   return d->bJobOK;
00372 }
00373 
00374 QString NetAccess::mimetypeInternal( const KUrl & url, QWidget* window )
00375 {
00376   d->bJobOK = true; // success unless further error occurs
00377   d->m_mimetype = QLatin1String("unknown");
00378   KIO::Job * job = KIO::mimetype( url );
00379   job->ui()->setWindow (window);
00380   connect( job, SIGNAL( result (KJob *) ),
00381            this, SLOT( slotResult (KJob *) ) );
00382   connect( job, SIGNAL( mimetype (KIO::Job *, const QString &) ),
00383            this, SLOT( slotMimetype (KIO::Job *, const QString &) ) );
00384   enter_loop();
00385   return d->m_mimetype;
00386 }
00387 
00388 void NetAccess::slotMimetype( KIO::Job *, const QString & type  )
00389 {
00390   d->m_mimetype = type;
00391 }
00392 
00393 QString NetAccess::fish_executeInternal(const KUrl & url, const QString &command, QWidget* window)
00394 {
00395   QString target, remoteTempFileName, resultData;
00396   KUrl tempPathUrl;
00397   KTemporaryFile tmpFile;
00398   tmpFile.open();
00399 
00400   if( url.protocol() == "fish" )
00401   {
00402     // construct remote temp filename
00403     tempPathUrl = url;
00404     remoteTempFileName = tmpFile.fileName();
00405     // only need the filename KTempFile adds some KDE specific dirs
00406     // that probably does not exist on the remote side
00407     int pos = remoteTempFileName.lastIndexOf('/');
00408     remoteTempFileName = "/tmp/fishexec_" + remoteTempFileName.mid(pos + 1);
00409     tempPathUrl.setPath( remoteTempFileName );
00410     d->bJobOK = true; // success unless further error occurs
00411     QByteArray packedArgs;
00412     QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00413 
00414     stream << int('X') << tempPathUrl << command;
00415 
00416     KIO::Job * job = KIO::special( tempPathUrl, packedArgs );
00417     job->ui()->setWindow( window );
00418     connect( job, SIGNAL( result (KJob *) ),
00419              this, SLOT( slotResult (KJob *) ) );
00420     enter_loop();
00421 
00422     // since the KIO::special does not provide feedback we need to download the result
00423     if( NetAccess::download( tempPathUrl, target, window ) )
00424     {
00425       QFile resultFile( target );
00426 
00427       if (resultFile.open( QIODevice::ReadOnly ))
00428       {
00429         QTextStream ts( &resultFile ); // default encoding is Locale
00430         resultData = ts.readAll();
00431         resultFile.close();
00432         NetAccess::del( tempPathUrl, window );
00433       }
00434     }
00435   }
00436   else
00437   {
00438     resultData = i18n( "ERROR: Unknown protocol '%1'", url.protocol() );
00439   }
00440   return resultData;
00441 }
00442 
00443 bool NetAccess::synchronousRunInternal( Job* job, QWidget* window, QByteArray* data,
00444                                         KUrl* finalURL, QMap<QString,QString>* metaData )
00445 {
00446   if ( job->ui() ) job->ui()->setWindow( window );
00447 
00448   d->m_metaData = metaData;
00449   if ( d->m_metaData ) {
00450       for ( QMap<QString, QString>::iterator it = d->m_metaData->begin(); it != d->m_metaData->end(); ++it ) {
00451           job->addMetaData( it.key(), it.value() );
00452       }
00453   }
00454 
00455   if ( finalURL ) {
00456       SimpleJob *sj = qobject_cast<SimpleJob*>( job );
00457       if ( sj ) {
00458           d->m_url = sj->url();
00459       }
00460   }
00461 
00462   connect( job, SIGNAL( result (KJob *) ),
00463            this, SLOT( slotResult (KJob *) ) );
00464 
00465   const QMetaObject* meta = job->metaObject();
00466 
00467   static const char dataSignal[] = "data(KIO::Job*,QByteArray)";
00468   if ( meta->indexOfSignal( dataSignal ) != -1 ) {
00469       connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00470                this, SLOT(slotData(KIO::Job*,const QByteArray&)) );
00471   }
00472 
00473   static const char redirSignal[] = "redirection(KIO::Job*,KUrl)";
00474   if ( meta->indexOfSignal( redirSignal ) != -1 ) {
00475       connect( job, SIGNAL(redirection(KIO::Job*,const KUrl&)),
00476                this, SLOT(slotRedirection(KIO::Job*, const KUrl&)) );
00477   }
00478 
00479   enter_loop();
00480 
00481   if ( finalURL )
00482       *finalURL = d->m_url;
00483   if ( data )
00484       *data = d->m_data;
00485 
00486   return d->bJobOK;
00487 }
00488 
00489 void NetAccess::enter_loop()
00490 {
00491     QEventLoop eventLoop;
00492     connect(this, SIGNAL(leaveModality()),
00493             &eventLoop, SLOT(quit()));
00494     eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
00495 }
00496 
00497 void NetAccess::slotResult( KJob * job )
00498 {
00499   lastErrorCode = job->error();
00500   d->bJobOK = !job->error();
00501   if ( !d->bJobOK )
00502   {
00503     if ( !lastErrorMsg )
00504       lastErrorMsg = new QString;
00505     *lastErrorMsg = job->errorString();
00506   }
00507   KIO::StatJob* statJob = qobject_cast<KIO::StatJob *>( job );
00508   if ( statJob )
00509     d->m_entry = statJob->statResult();
00510 
00511   KIO::Job* kioJob = qobject_cast<KIO::Job *>( job );
00512   if ( kioJob && d->m_metaData )
00513     *d->m_metaData = kioJob->metaData();
00514 
00515   emit leaveModality();
00516 }
00517 
00518 void NetAccess::slotData( KIO::Job*, const QByteArray& data )
00519 {
00520   if ( data.isEmpty() )
00521     return;
00522 
00523   unsigned offset = d->m_data.size();
00524   d->m_data.resize( offset + data.size() );
00525   std::memcpy( d->m_data.data() + offset, data.data(), data.size() );
00526 }
00527 
00528 void NetAccess::slotRedirection( KIO::Job*, const KUrl& url )
00529 {
00530   d->m_url = url;
00531 }
00532 
00533 #include "netaccess.moc"

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal