• Skip to content
  • Skip to link menu
KDE 4.3 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.toLocalFile();
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.toLocalFile() == 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.toLocalFile() );
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.toLocalFile() );
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   // Disable autodeletion until we are back from this event loop (#170963)
00274   // We just have to hope people don't mess with setAutoDelete in slots connected to the job, though.
00275   const bool wasAutoDelete = job->isAutoDelete();
00276   job->setAutoDelete(false);
00277   const bool ok = kioNet.synchronousRunInternal(job, window, data, finalURL, metaData);
00278   if (wasAutoDelete) {
00279     job->deleteLater();
00280   }
00281   return ok;
00282 }
00283 
00284 QString NetAccess::mimetype( const KUrl& url, QWidget* window )
00285 {
00286   NetAccess kioNet;
00287   return kioNet.mimetypeInternal( url, window );
00288 }
00289 
00290 QString NetAccess::lastErrorString()
00291 {
00292     return lastErrorMsg ? *lastErrorMsg : QString();
00293 }
00294 
00295 int NetAccess::lastError()
00296 {
00297     return lastErrorCode;
00298 }
00299 
00300 void NetAccess::removeTempFile(const QString& name)
00301 {
00302   if (!tmpfiles)
00303     return;
00304   if (tmpfiles->contains(name))
00305   {
00306     unlink(QFile::encodeName(name));
00307     tmpfiles->removeAll(name);
00308   }
00309 }
00310 
00311 bool NetAccess::filecopyInternal(const KUrl& src, const KUrl& target, int permissions,
00312                                  KIO::JobFlags flags, QWidget* window, bool move)
00313 {
00314   d->bJobOK = true; // success unless further error occurs
00315 
00316   KIO::Scheduler::checkSlaveOnHold(true);
00317   KIO::Job * job = move
00318                    ? KIO::file_move( src, target, permissions, flags )
00319                    : KIO::file_copy( src, target, permissions, flags );
00320   job->ui()->setWindow (window);
00321   connect( job, SIGNAL( result (KJob *) ),
00322            this, SLOT( slotResult (KJob *) ) );
00323 
00324   enter_loop();
00325   return d->bJobOK;
00326 }
00327 
00328 bool NetAccess::dircopyInternal(const KUrl::List& src, const KUrl& target,
00329                                 QWidget* window, bool move)
00330 {
00331   d->bJobOK = true; // success unless further error occurs
00332 
00333   KIO::Job * job = move
00334                    ? KIO::move( src, target )
00335                    : KIO::copy( src, target );
00336   job->ui()->setWindow (window);
00337   connect( job, SIGNAL( result (KJob *) ),
00338            this, SLOT( slotResult (KJob *) ) );
00339 
00340   enter_loop();
00341   return d->bJobOK;
00342 }
00343 
00344 bool NetAccess::statInternal( const KUrl & url, int details, StatSide side,
00345                               QWidget* window )
00346 {
00347   d->bJobOK = true; // success unless further error occurs
00348   KIO::JobFlags flags = url.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags;
00349   KIO::StatJob * job = KIO::stat( url, flags );
00350   job->ui()->setWindow (window);
00351   job->setDetails( details );
00352   job->setSide( side == SourceSide ? StatJob::SourceSide : StatJob::DestinationSide );
00353   connect( job, SIGNAL( result (KJob *) ),
00354            this, SLOT( slotResult (KJob *) ) );
00355   enter_loop();
00356   return d->bJobOK;
00357 }
00358 
00359 bool NetAccess::delInternal( const KUrl & url, QWidget* window )
00360 {
00361   d->bJobOK = true; // success unless further error occurs
00362   KIO::Job * job = KIO::del( url );
00363   job->ui()->setWindow (window);
00364   connect( job, SIGNAL( result (KJob *) ),
00365            this, SLOT( slotResult (KJob *) ) );
00366   enter_loop();
00367   return d->bJobOK;
00368 }
00369 
00370 bool NetAccess::mkdirInternal( const KUrl & url, int permissions,
00371                                QWidget* window )
00372 {
00373   d->bJobOK = true; // success unless further error occurs
00374   KIO::Job * job = KIO::mkdir( url, permissions );
00375   job->ui()->setWindow (window);
00376   connect( job, SIGNAL( result (KJob *) ),
00377            this, SLOT( slotResult (KJob *) ) );
00378   enter_loop();
00379   return d->bJobOK;
00380 }
00381 
00382 QString NetAccess::mimetypeInternal( const KUrl & url, QWidget* window )
00383 {
00384   d->bJobOK = true; // success unless further error occurs
00385   d->m_mimetype = QLatin1String("unknown");
00386   KIO::Job * job = KIO::mimetype( url );
00387   job->ui()->setWindow (window);
00388   connect( job, SIGNAL( result (KJob *) ),
00389            this, SLOT( slotResult (KJob *) ) );
00390   connect( job, SIGNAL( mimetype (KIO::Job *, const QString &) ),
00391            this, SLOT( slotMimetype (KIO::Job *, const QString &) ) );
00392   enter_loop();
00393   return d->m_mimetype;
00394 }
00395 
00396 void NetAccess::slotMimetype( KIO::Job *, const QString & type  )
00397 {
00398   d->m_mimetype = type;
00399 }
00400 
00401 QString NetAccess::fish_executeInternal(const KUrl & url, const QString &command, QWidget* window)
00402 {
00403   QString target, remoteTempFileName, resultData;
00404   KUrl tempPathUrl;
00405   KTemporaryFile tmpFile;
00406   tmpFile.open();
00407 
00408   if( url.protocol() == "fish" )
00409   {
00410     // construct remote temp filename
00411     tempPathUrl = url;
00412     remoteTempFileName = tmpFile.fileName();
00413     // only need the filename KTempFile adds some KDE specific dirs
00414     // that probably does not exist on the remote side
00415     int pos = remoteTempFileName.lastIndexOf('/');
00416     remoteTempFileName = "/tmp/fishexec_" + remoteTempFileName.mid(pos + 1);
00417     tempPathUrl.setPath( remoteTempFileName );
00418     d->bJobOK = true; // success unless further error occurs
00419     QByteArray packedArgs;
00420     QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00421 
00422     stream << int('X') << tempPathUrl << command;
00423 
00424     KIO::Job * job = KIO::special( tempPathUrl, packedArgs );
00425     job->ui()->setWindow( window );
00426     connect( job, SIGNAL( result (KJob *) ),
00427              this, SLOT( slotResult (KJob *) ) );
00428     enter_loop();
00429 
00430     // since the KIO::special does not provide feedback we need to download the result
00431     if( NetAccess::download( tempPathUrl, target, window ) )
00432     {
00433       QFile resultFile( target );
00434 
00435       if (resultFile.open( QIODevice::ReadOnly ))
00436       {
00437         QTextStream ts( &resultFile ); // default encoding is Locale
00438         resultData = ts.readAll();
00439         resultFile.close();
00440         NetAccess::del( tempPathUrl, window );
00441       }
00442     }
00443   }
00444   else
00445   {
00446     resultData = i18n( "ERROR: Unknown protocol '%1'", url.protocol() );
00447   }
00448   return resultData;
00449 }
00450 
00451 bool NetAccess::synchronousRunInternal( Job* job, QWidget* window, QByteArray* data,
00452                                         KUrl* finalURL, QMap<QString,QString>* metaData )
00453 {
00454   if ( job->ui() ) job->ui()->setWindow( window );
00455 
00456   d->m_metaData = metaData;
00457   if ( d->m_metaData ) {
00458       for ( QMap<QString, QString>::iterator it = d->m_metaData->begin(); it != d->m_metaData->end(); ++it ) {
00459           job->addMetaData( it.key(), it.value() );
00460       }
00461   }
00462 
00463   if ( finalURL ) {
00464       SimpleJob *sj = qobject_cast<SimpleJob*>( job );
00465       if ( sj ) {
00466           d->m_url = sj->url();
00467       }
00468   }
00469 
00470   connect( job, SIGNAL( result (KJob *) ),
00471            this, SLOT( slotResult (KJob *) ) );
00472 
00473   const QMetaObject* meta = job->metaObject();
00474 
00475   static const char dataSignal[] = "data(KIO::Job*,QByteArray)";
00476   if ( meta->indexOfSignal( dataSignal ) != -1 ) {
00477       connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00478                this, SLOT(slotData(KIO::Job*,const QByteArray&)) );
00479   }
00480 
00481   static const char redirSignal[] = "redirection(KIO::Job*,KUrl)";
00482   if ( meta->indexOfSignal( redirSignal ) != -1 ) {
00483       connect( job, SIGNAL(redirection(KIO::Job*,const KUrl&)),
00484                this, SLOT(slotRedirection(KIO::Job*, const KUrl&)) );
00485   }
00486 
00487   enter_loop();
00488 
00489   if ( finalURL )
00490       *finalURL = d->m_url;
00491   if ( data )
00492       *data = d->m_data;
00493 
00494   return d->bJobOK;
00495 }
00496 
00497 void NetAccess::enter_loop()
00498 {
00499     QEventLoop eventLoop;
00500     connect(this, SIGNAL(leaveModality()),
00501             &eventLoop, SLOT(quit()));
00502     eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
00503 }
00504 
00505 void NetAccess::slotResult( KJob * job )
00506 {
00507   lastErrorCode = job->error();
00508   d->bJobOK = !job->error();
00509   if ( !d->bJobOK )
00510   {
00511     if ( !lastErrorMsg )
00512       lastErrorMsg = new QString;
00513     *lastErrorMsg = job->errorString();
00514   }
00515   KIO::StatJob* statJob = qobject_cast<KIO::StatJob *>( job );
00516   if ( statJob )
00517     d->m_entry = statJob->statResult();
00518 
00519   KIO::Job* kioJob = qobject_cast<KIO::Job *>( job );
00520   if ( kioJob && d->m_metaData )
00521     *d->m_metaData = kioJob->metaData();
00522 
00523   emit leaveModality();
00524 }
00525 
00526 void NetAccess::slotData( KIO::Job*, const QByteArray& data )
00527 {
00528   if ( data.isEmpty() )
00529     return;
00530 
00531   unsigned offset = d->m_data.size();
00532   d->m_data.resize( offset + data.size() );
00533   std::memcpy( d->m_data.data() + offset, data.data(), data.size() );
00534 }
00535 
00536 void NetAccess::slotRedirection( KIO::Job*, const KUrl& url )
00537 {
00538   d->m_url = url;
00539 }
00540 
00541 #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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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