• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • 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 #ifndef KDE_NO_DEPRECATED
00153 bool NetAccess::copy( const KUrl& src, const KUrl& target, QWidget* window )
00154 {
00155     return file_copy( src, target, window );
00156 }
00157 #endif
00158 
00159 // bool NetAccess::file_copy( const KUrl& src, const KUrl& target, int permissions,
00160 //                            bool overwrite, bool resume, QWidget* window )
00161 // {
00162 //   NetAccess kioNet;
00163 //   return kioNet.filecopyInternal( src, target, permissions, overwrite, resume,
00164 //                                   window, false /*copy*/ );
00165 // }
00166 
00167 
00168 // bool NetAccess::file_move( const KUrl& src, const KUrl& target, int permissions,
00169 //                            bool overwrite, bool resume, QWidget* window )
00170 // {
00171 //   NetAccess kioNet;
00172 //   return kioNet.filecopyInternal( src, target, permissions, overwrite, resume,
00173 //                                   window, true /*move*/ );
00174 // }
00175 
00176 bool NetAccess::dircopy( const KUrl & src, const KUrl & target, QWidget* window )
00177 {
00178   KUrl::List srcList;
00179   srcList.append( src );
00180   return NetAccess::dircopy( srcList, target, window );
00181 }
00182 
00183 bool NetAccess::dircopy( const KUrl::List & srcList, const KUrl & target, QWidget* window )
00184 {
00185   NetAccess kioNet;
00186   return kioNet.dircopyInternal( srcList, target, window, false /*copy*/ );
00187 }
00188 
00189 #ifndef KDE_NO_DEPRECATED
00190 bool NetAccess::move( const KUrl& src, const KUrl& target, QWidget* window )
00191 {
00192   KUrl::List srcList;
00193   srcList.append( src );
00194   NetAccess kioNet;
00195   return kioNet.dircopyInternal( srcList, target, window, true /*move*/ );
00196 }
00197 #endif
00198 
00199 #ifndef KDE_NO_DEPRECATED
00200 bool NetAccess::move( const KUrl::List& srcList, const KUrl& target, QWidget* window )
00201 {
00202   NetAccess kioNet;
00203   return kioNet.dircopyInternal( srcList, target, window, true /*move*/ );
00204 }
00205 #endif
00206 
00207 #ifndef KDE_NO_DEPRECATED
00208 bool NetAccess::exists( const KUrl & url, bool source, QWidget* window )
00209 {
00210   if ( url.isLocalFile() )
00211     return QFile::exists( url.toLocalFile() );
00212   NetAccess kioNet;
00213   return kioNet.statInternal( url, 0 /*no details*/,
00214                               source ? SourceSide : DestinationSide, window );
00215 }
00216 #endif
00217 
00218 bool NetAccess::exists( const KUrl & url, StatSide side, QWidget* window )
00219 {
00220   if ( url.isLocalFile() )
00221     return QFile::exists( url.toLocalFile() );
00222   NetAccess kioNet;
00223   return kioNet.statInternal( url, 0 /*no details*/, side, window );
00224 }
00225 
00226 bool NetAccess::stat( const KUrl & url, KIO::UDSEntry & entry, QWidget* window )
00227 {
00228   NetAccess kioNet;
00229   bool ret = kioNet.statInternal( url, 2 /*all details*/, SourceSide, window );
00230   if (ret)
00231     entry = kioNet.d->m_entry;
00232   return ret;
00233 }
00234 
00235 KUrl NetAccess::mostLocalUrl(const KUrl & url, QWidget* window)
00236 {
00237   if ( url.isLocalFile() )
00238   {
00239     return url;
00240   }
00241 
00242   KIO::UDSEntry entry;
00243   if (!stat(url, entry, window))
00244   {
00245     return url;
00246   }
00247 
00248   const QString path = entry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
00249   if ( !path.isEmpty() )
00250   {
00251     KUrl new_url;
00252     new_url.setPath(path);
00253     return new_url;
00254   }
00255 
00256   return url;
00257 }
00258 
00259 bool NetAccess::del( const KUrl & url, QWidget* window )
00260 {
00261   NetAccess kioNet;
00262   return kioNet.delInternal( url, window );
00263 }
00264 
00265 bool NetAccess::mkdir( const KUrl & url, QWidget* window, int permissions )
00266 {
00267   NetAccess kioNet;
00268   return kioNet.mkdirInternal( url, permissions, window );
00269 }
00270 
00271 QString NetAccess::fish_execute( const KUrl & url, const QString &command, QWidget* window )
00272 {
00273   NetAccess kioNet;
00274   return kioNet.fish_executeInternal( url, command, window );
00275 }
00276 
00277 bool NetAccess::synchronousRun( Job* job, QWidget* window, QByteArray* data,
00278                                 KUrl* finalURL, QMap<QString, QString>* metaData )
00279 {
00280   NetAccess kioNet;
00281   // Disable autodeletion until we are back from this event loop (#170963)
00282   // We just have to hope people don't mess with setAutoDelete in slots connected to the job, though.
00283   const bool wasAutoDelete = job->isAutoDelete();
00284   job->setAutoDelete(false);
00285   const bool ok = kioNet.synchronousRunInternal(job, window, data, finalURL, metaData);
00286   if (wasAutoDelete) {
00287     job->deleteLater();
00288   }
00289   return ok;
00290 }
00291 
00292 QString NetAccess::mimetype( const KUrl& url, QWidget* window )
00293 {
00294   NetAccess kioNet;
00295   return kioNet.mimetypeInternal( url, window );
00296 }
00297 
00298 QString NetAccess::lastErrorString()
00299 {
00300     return lastErrorMsg ? *lastErrorMsg : QString();
00301 }
00302 
00303 int NetAccess::lastError()
00304 {
00305     return lastErrorCode;
00306 }
00307 
00308 void NetAccess::removeTempFile(const QString& name)
00309 {
00310   if (!tmpfiles)
00311     return;
00312   if (tmpfiles->contains(name))
00313   {
00314     unlink(QFile::encodeName(name));
00315     tmpfiles->removeAll(name);
00316   }
00317 }
00318 
00319 bool NetAccess::filecopyInternal(const KUrl& src, const KUrl& target, int permissions,
00320                                  KIO::JobFlags flags, QWidget* window, bool move)
00321 {
00322   d->bJobOK = true; // success unless further error occurs
00323 
00324   KIO::Scheduler::checkSlaveOnHold(true);
00325   KIO::Job * job = move
00326                    ? KIO::file_move( src, target, permissions, flags )
00327                    : KIO::file_copy( src, target, permissions, flags );
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::dircopyInternal(const KUrl::List& src, const KUrl& target,
00337                                 QWidget* window, bool move)
00338 {
00339   d->bJobOK = true; // success unless further error occurs
00340 
00341   KIO::Job * job = move
00342                    ? KIO::move( src, target )
00343                    : KIO::copy( src, target );
00344   job->ui()->setWindow (window);
00345   connect( job, SIGNAL( result (KJob *) ),
00346            this, SLOT( slotResult (KJob *) ) );
00347 
00348   enter_loop();
00349   return d->bJobOK;
00350 }
00351 
00352 bool NetAccess::statInternal( const KUrl & url, int details, StatSide side,
00353                               QWidget* window )
00354 {
00355   d->bJobOK = true; // success unless further error occurs
00356   KIO::JobFlags flags = url.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags;
00357   KIO::StatJob * job = KIO::stat( url, flags );
00358   job->ui()->setWindow (window);
00359   job->setDetails( details );
00360   job->setSide( side == SourceSide ? StatJob::SourceSide : StatJob::DestinationSide );
00361   connect( job, SIGNAL( result (KJob *) ),
00362            this, SLOT( slotResult (KJob *) ) );
00363   enter_loop();
00364   return d->bJobOK;
00365 }
00366 
00367 bool NetAccess::delInternal( const KUrl & url, QWidget* window )
00368 {
00369   d->bJobOK = true; // success unless further error occurs
00370   KIO::Job * job = KIO::del( url );
00371   job->ui()->setWindow (window);
00372   connect( job, SIGNAL( result (KJob *) ),
00373            this, SLOT( slotResult (KJob *) ) );
00374   enter_loop();
00375   return d->bJobOK;
00376 }
00377 
00378 bool NetAccess::mkdirInternal( const KUrl & url, int permissions,
00379                                QWidget* window )
00380 {
00381   d->bJobOK = true; // success unless further error occurs
00382   KIO::Job * job = KIO::mkdir( url, permissions );
00383   job->ui()->setWindow (window);
00384   connect( job, SIGNAL( result (KJob *) ),
00385            this, SLOT( slotResult (KJob *) ) );
00386   enter_loop();
00387   return d->bJobOK;
00388 }
00389 
00390 QString NetAccess::mimetypeInternal( const KUrl & url, QWidget* window )
00391 {
00392   d->bJobOK = true; // success unless further error occurs
00393   d->m_mimetype = QLatin1String("unknown");
00394   KIO::Job * job = KIO::mimetype( url );
00395   job->ui()->setWindow (window);
00396   connect( job, SIGNAL( result (KJob *) ),
00397            this, SLOT( slotResult (KJob *) ) );
00398   connect( job, SIGNAL( mimetype (KIO::Job *, const QString &) ),
00399            this, SLOT( slotMimetype (KIO::Job *, const QString &) ) );
00400   enter_loop();
00401   return d->m_mimetype;
00402 }
00403 
00404 void NetAccess::slotMimetype( KIO::Job *, const QString & type  )
00405 {
00406   d->m_mimetype = type;
00407 }
00408 
00409 QString NetAccess::fish_executeInternal(const KUrl & url, const QString &command, QWidget* window)
00410 {
00411   QString target, remoteTempFileName, resultData;
00412   KUrl tempPathUrl;
00413   KTemporaryFile tmpFile;
00414   tmpFile.open();
00415 
00416   if( url.protocol() == "fish" )
00417   {
00418     // construct remote temp filename
00419     tempPathUrl = url;
00420     remoteTempFileName = tmpFile.fileName();
00421     // only need the filename KTempFile adds some KDE specific dirs
00422     // that probably does not exist on the remote side
00423     int pos = remoteTempFileName.lastIndexOf('/');
00424     remoteTempFileName = "/tmp/fishexec_" + remoteTempFileName.mid(pos + 1);
00425     tempPathUrl.setPath( remoteTempFileName );
00426     d->bJobOK = true; // success unless further error occurs
00427     QByteArray packedArgs;
00428     QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00429 
00430     stream << int('X') << tempPathUrl << command;
00431 
00432     KIO::Job * job = KIO::special( tempPathUrl, packedArgs );
00433     job->ui()->setWindow( window );
00434     connect( job, SIGNAL( result (KJob *) ),
00435              this, SLOT( slotResult (KJob *) ) );
00436     enter_loop();
00437 
00438     // since the KIO::special does not provide feedback we need to download the result
00439     if( NetAccess::download( tempPathUrl, target, window ) )
00440     {
00441       QFile resultFile( target );
00442 
00443       if (resultFile.open( QIODevice::ReadOnly ))
00444       {
00445         QTextStream ts( &resultFile ); // default encoding is Locale
00446         resultData = ts.readAll();
00447         resultFile.close();
00448         NetAccess::del( tempPathUrl, window );
00449       }
00450     }
00451   }
00452   else
00453   {
00454     resultData = i18n( "ERROR: Unknown protocol '%1'", url.protocol() );
00455   }
00456   return resultData;
00457 }
00458 
00459 bool NetAccess::synchronousRunInternal( Job* job, QWidget* window, QByteArray* data,
00460                                         KUrl* finalURL, QMap<QString,QString>* metaData )
00461 {
00462   if ( job->ui() ) job->ui()->setWindow( window );
00463 
00464   d->m_metaData = metaData;
00465   if ( d->m_metaData ) {
00466       for ( QMap<QString, QString>::iterator it = d->m_metaData->begin(); it != d->m_metaData->end(); ++it ) {
00467           job->addMetaData( it.key(), it.value() );
00468       }
00469   }
00470 
00471   if ( finalURL ) {
00472       SimpleJob *sj = qobject_cast<SimpleJob*>( job );
00473       if ( sj ) {
00474           d->m_url = sj->url();
00475       }
00476   }
00477 
00478   connect( job, SIGNAL( result (KJob *) ),
00479            this, SLOT( slotResult (KJob *) ) );
00480 
00481   const QMetaObject* meta = job->metaObject();
00482 
00483   static const char dataSignal[] = "data(KIO::Job*,QByteArray)";
00484   if ( meta->indexOfSignal( dataSignal ) != -1 ) {
00485       connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00486                this, SLOT(slotData(KIO::Job*,const QByteArray&)) );
00487   }
00488 
00489   static const char redirSignal[] = "redirection(KIO::Job*,KUrl)";
00490   if ( meta->indexOfSignal( redirSignal ) != -1 ) {
00491       connect( job, SIGNAL(redirection(KIO::Job*,const KUrl&)),
00492                this, SLOT(slotRedirection(KIO::Job*, const KUrl&)) );
00493   }
00494 
00495   enter_loop();
00496 
00497   if ( finalURL )
00498       *finalURL = d->m_url;
00499   if ( data )
00500       *data = d->m_data;
00501 
00502   return d->bJobOK;
00503 }
00504 
00505 void NetAccess::enter_loop()
00506 {
00507     QEventLoop eventLoop;
00508     connect(this, SIGNAL(leaveModality()),
00509             &eventLoop, SLOT(quit()));
00510     eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
00511 }
00512 
00513 void NetAccess::slotResult( KJob * job )
00514 {
00515   lastErrorCode = job->error();
00516   d->bJobOK = !job->error();
00517   if ( !d->bJobOK )
00518   {
00519     if ( !lastErrorMsg )
00520       lastErrorMsg = new QString;
00521     *lastErrorMsg = job->errorString();
00522   }
00523   KIO::StatJob* statJob = qobject_cast<KIO::StatJob *>( job );
00524   if ( statJob )
00525     d->m_entry = statJob->statResult();
00526 
00527   KIO::Job* kioJob = qobject_cast<KIO::Job *>( job );
00528   if ( kioJob && d->m_metaData )
00529     *d->m_metaData = kioJob->metaData();
00530 
00531   emit leaveModality();
00532 }
00533 
00534 void NetAccess::slotData( KIO::Job*, const QByteArray& data )
00535 {
00536   if ( data.isEmpty() )
00537     return;
00538 
00539   unsigned offset = d->m_data.size();
00540   d->m_data.resize( offset + data.size() );
00541   std::memcpy( d->m_data.data() + offset, data.data(), data.size() );
00542 }
00543 
00544 void NetAccess::slotRedirection( KIO::Job*, const KUrl& url )
00545 {
00546   d->m_url = url;
00547 }
00548 
00549 #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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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