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

KIO

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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.5
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