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

KIO

slaveinterface.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 David Faure <faure@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "slaveinterface.h"
00020 #include "slaveinterface_p.h"
00021 
00022 #include "slavebase.h"
00023 #include "connection.h"
00024 #include <errno.h>
00025 #include <assert.h>
00026 #include <kdebug.h>
00027 #include <stdlib.h>
00028 #include <sys/time.h>
00029 #include <unistd.h>
00030 #include <signal.h>
00031 #include <klocale.h>
00032 #include <kapplication.h>
00033 #include <ksslinfodialog.h>
00034 #include <ksslcertificate.h>
00035 #include <ksslcertchain.h>
00036 #include <kmessagebox.h>
00037 #include <time.h>
00038 #include <QtDBus/QtDBus>
00039 #include <QtCore/QPointer>
00040 #include <QtNetwork/QSslCertificate>
00041 #include <QtNetwork/QSslError>
00042 
00043 using namespace KIO;
00044 
00045 
00046 SlaveInterface::SlaveInterface(SlaveInterfacePrivate &dd, QObject *parent)
00047     : QObject(parent), d_ptr(&dd)
00048 {
00049     connect(&d_ptr->speed_timer, SIGNAL(timeout()), SLOT(calcSpeed()));
00050 }
00051 
00052 SlaveInterface::~SlaveInterface()
00053 {
00054     // Note: no kDebug() here (scheduler is deleted very late)
00055 
00056     delete d_ptr;
00057 }
00058 
00059 void SlaveInterface::setConnection( Connection* connection )
00060 {
00061     Q_D(SlaveInterface);
00062     d->connection = connection;
00063 }
00064 
00065 Connection *SlaveInterface::connection() const
00066 {
00067     const Q_D(SlaveInterface);
00068     return d->connection;
00069 }
00070 
00071 static KIO::filesize_t readFilesize_t(QDataStream &stream)
00072 {
00073     KIO::filesize_t result;
00074     stream >> result;
00075     return result;
00076 }
00077 
00078 bool SlaveInterface::dispatch()
00079 {
00080     Q_D(SlaveInterface);
00081     assert( d->connection );
00082 
00083     int cmd;
00084     QByteArray data;
00085 
00086     int ret = d->connection->read( &cmd, data );
00087     if (ret == -1)
00088       return false;
00089 
00090     return dispatch( cmd, data );
00091 }
00092 
00093 void SlaveInterface::calcSpeed()
00094 {
00095     Q_D(SlaveInterface);
00096     if (d->slave_calcs_speed) {
00097         d->speed_timer.stop();
00098         return;
00099     }
00100 
00101     struct timeval tv;
00102     gettimeofday(&tv, 0);
00103 
00104     long diff = ((tv.tv_sec - d->start_time.tv_sec) * 1000000 +
00105                   tv.tv_usec - d->start_time.tv_usec) / 1000;
00106     if (diff - d->last_time >= 900) {
00107         d->last_time = diff;
00108         if (d->nums == max_nums) {
00109             // let's hope gcc can optimize that well enough
00110             // otherwise I'd try memcpy :)
00111             for (unsigned int i = 1; i < max_nums; ++i) {
00112                 d->times[i-1] = d->times[i];
00113                 d->sizes[i-1] = d->sizes[i];
00114             }
00115             d->nums--;
00116         }
00117         d->times[d->nums] = diff;
00118         d->sizes[d->nums++] = d->filesize - d->offset;
00119 
00120         KIO::filesize_t lspeed = 1000 * (d->sizes[d->nums-1] - d->sizes[0]) / (d->times[d->nums-1] - d->times[0]);
00121 
00122 //      kDebug() << (long)d->filesize << diff
00123 //          << long(d->sizes[d->nums-1] - d->sizes[0])
00124 //          << d->times[d->nums-1] - d->times[0]
00125 //          << long(lspeed) << double(d->filesize) / diff
00126 //          << convertSize(lspeed)
00127 //          << convertSize(long(double(d->filesize) / diff) * 1000);
00128 
00129         if (!lspeed) {
00130             d->nums = 1;
00131             d->times[0] = diff;
00132             d->sizes[0] = d->filesize - d->offset;
00133         }
00134         emit speed(lspeed);
00135     }
00136 }
00137 
00138 #ifndef KDE_USE_FINAL // already defined in slavebase.cpp
00139 /*
00140  * Map pid_t to a signed integer type that makes sense for QByteArray;
00141  * only the most common sizes 16 bit and 32 bit are special-cased.
00142  */
00143 template<int T> struct PIDType { typedef pid_t PID_t; } ;
00144 template<> struct PIDType<2> { typedef qint16 PID_t; } ;
00145 template<> struct PIDType<4> { typedef qint32 PID_t; } ;
00146 #endif
00147 
00148 bool SlaveInterface::dispatch( int _cmd, const QByteArray &rawdata )
00149 {
00150     Q_D(SlaveInterface);
00151     //kDebug(7007) << "dispatch " << _cmd;
00152 
00153     QDataStream stream( rawdata );
00154 
00155     QString str1;
00156     qint32 i;
00157     qint8 b;
00158     quint32 ul;
00159 
00160     switch( _cmd ) {
00161     case MSG_DATA:
00162     emit data( rawdata );
00163     break;
00164     case MSG_DATA_REQ:
00165         emit dataReq();
00166     break;
00167     case MSG_OPENED: {
00168     emit open();
00169     break;
00170     }
00171     case MSG_FINISHED:
00172     //kDebug(7007) << "Finished [this = " << this << "]";
00173         d->offset = 0;
00174         d->speed_timer.stop();
00175     emit finished();
00176     break;
00177     case MSG_STAT_ENTRY:
00178     {
00179         UDSEntry entry;
00180         stream >> entry;
00181         emit statEntry(entry);
00182     }
00183     break;
00184     case MSG_LIST_ENTRIES:
00185     {
00186         quint32 count;
00187         stream >> count;
00188 
00189         UDSEntryList list;
00190         UDSEntry entry;
00191         for (uint i = 0; i < count; i++) {
00192         stream >> entry;
00193         list.append(entry);
00194         }
00195         emit listEntries(list);
00196 
00197     }
00198     break;
00199     case MSG_RESUME: // From the put job
00200     {
00201         d->offset = readFilesize_t(stream);
00202         emit canResume( d->offset );
00203     }
00204     break;
00205     case MSG_CANRESUME: // From the get job
00206         d->filesize = d->offset;
00207         emit canResume(0); // the arg doesn't matter
00208         break;
00209     case MSG_ERROR:
00210     stream >> i >> str1;
00211     kDebug(7007) << "error " << i << " " << str1;
00212     emit error( i, str1 );
00213     break;
00214     case MSG_SLAVE_STATUS:
00215         {
00216            PIDType<sizeof(pid_t)>::PID_t stream_pid;
00217            pid_t pid;
00218            QByteArray protocol;
00219            stream >> stream_pid >> protocol >> str1 >> b;
00220            pid = stream_pid;
00221            emit slaveStatus(pid, protocol, str1, (b != 0));
00222         }
00223         break;
00224     case MSG_CONNECTED:
00225         emit connected();
00226         break;
00227 
00228     case MSG_WRITTEN:
00229     {
00230         KIO::filesize_t size = readFilesize_t(stream);
00231         emit written( size );
00232     }
00233     break;
00234     case INF_TOTAL_SIZE:
00235     {
00236         KIO::filesize_t size = readFilesize_t(stream);
00237         gettimeofday(&d->start_time, 0);
00238         d->last_time = 0;
00239         d->filesize = d->offset;
00240         d->sizes[0] = d->filesize - d->offset;
00241         d->times[0] = 0;
00242         d->nums = 1;
00243         d->speed_timer.start(1000);
00244         d->slave_calcs_speed = false;
00245         emit totalSize( size );
00246     }
00247     break;
00248     case INF_PROCESSED_SIZE:
00249     {
00250         KIO::filesize_t size = readFilesize_t(stream);
00251         emit processedSize( size );
00252         d->filesize = size;
00253     }
00254     break;
00255     case INF_POSITION:
00256     {
00257         KIO::filesize_t pos = readFilesize_t(stream);
00258         emit position( pos );
00259     }
00260     break;
00261     case INF_SPEED:
00262     stream >> ul;
00263     d->slave_calcs_speed = true;
00264     d->speed_timer.stop();
00265 
00266     emit speed( ul );
00267     break;
00268     case INF_GETTING_FILE:
00269     break;
00270     case INF_ERROR_PAGE:
00271     emit errorPage();
00272     break;
00273     case INF_REDIRECTION:
00274       {
00275     KUrl url;
00276     stream >> url;
00277 
00278     emit redirection( url );
00279       }
00280       break;
00281     case INF_MIME_TYPE:
00282     stream >> str1;
00283 
00284     emit mimeType( str1 );
00285         if (!d->connection->suspended())
00286             d->connection->sendnow( CMD_NONE, QByteArray() );
00287     break;
00288     case INF_WARNING:
00289     stream >> str1;
00290 
00291     emit warning( str1 );
00292     break;
00293     case INF_MESSAGEBOX: {
00294     kDebug(7007) << "needs a msg box";
00295     QString text, caption, buttonYes, buttonNo, dontAskAgainName;
00296     int type;
00297     stream >> type >> text >> caption >> buttonYes >> buttonNo;
00298     if (stream.atEnd())
00299     messageBox(type, text, caption, buttonYes, buttonNo);
00300     else {
00301         stream >> dontAskAgainName;
00302         messageBox(type, text, caption, buttonYes, buttonNo, dontAskAgainName);
00303     }
00304     break;
00305     }
00306     case INF_INFOMESSAGE: {
00307         QString msg;
00308         stream >> msg;
00309         emit infoMessage(msg);
00310         break;
00311     }
00312     case INF_META_DATA: {
00313         MetaData meta_data;
00314         stream >> meta_data;
00315         d->m_incomingMetaData += meta_data;
00316 //         kDebug(7007) << "incoming metadata now" << d->m_incomingMetaData
00317 //                  << "\n newly arrived metadata is" << meta_data;
00318         emit metaData(meta_data);
00319         break;
00320     }
00321     case MSG_NET_REQUEST: {
00322         QString host;
00323         QString slaveid;
00324         stream >> host >> slaveid;
00325         requestNetwork(host, slaveid);
00326         break;
00327     }
00328     case MSG_NET_DROP: {
00329         QString host;
00330     QString slaveid;
00331         stream >> host >> slaveid;
00332         dropNetwork(host, slaveid);
00333         break;
00334     }
00335     case MSG_NEED_SUBURL_DATA: {
00336         emit needSubUrlData();
00337         break;
00338     }
00339     default:
00340         kWarning(7007) << "Slave sends unknown command (" << _cmd << "), dropping slave";
00341         return false;
00342     }
00343     return true;
00344 }
00345 
00346 void SlaveInterface::setOffset( KIO::filesize_t o)
00347 {
00348     Q_D(SlaveInterface);
00349     d->offset = o;
00350 }
00351 
00352 KIO::filesize_t SlaveInterface::offset() const
00353 {
00354     const Q_D(SlaveInterface);
00355     return d->offset;
00356 }
00357 
00358 void SlaveInterface::requestNetwork(const QString &host, const QString &slaveid)
00359 {
00360     Q_D(SlaveInterface);
00361     kDebug(7007) << "requestNetwork " << host << slaveid;
00362     QByteArray packedArgs;
00363     QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00364     stream << true;
00365     d->connection->sendnow( INF_NETWORK_STATUS, packedArgs );
00366 }
00367 
00368 void SlaveInterface::dropNetwork(const QString &host, const QString &slaveid)
00369 {
00370     kDebug(7007) << "dropNetwork " << host << slaveid;
00371 }
00372 
00373 void SlaveInterface::sendResumeAnswer( bool resume )
00374 {
00375     Q_D(SlaveInterface);
00376     kDebug(7007) << "ok for resuming:" << resume;
00377     d->connection->sendnow( resume ? CMD_RESUMEANSWER : CMD_NONE, QByteArray() );
00378 }
00379 
00380 void SlaveInterface::messageBox( int type, const QString &text, const QString &_caption,
00381                                  const QString &buttonYes, const QString &buttonNo )
00382 {
00383     messageBox( type, text, _caption, buttonYes, buttonNo, QString() );
00384 }
00385 
00386 void SlaveInterface::messageBox( int type, const QString &text, const QString &caption,
00387                                  const QString &buttonYes, const QString &buttonNo, const QString &dontAskAgainName )
00388 {
00389     Q_D(SlaveInterface);
00390     kDebug(7007) << "messageBox " << type << " " << text << " - " << caption << " " << dontAskAgainName;
00391     QByteArray packedArgs;
00392     QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00393 
00394     QPointer<SlaveInterface> me = this;
00395     if (d->connection) d->connection->suspend();
00396     int result = d->messageBox( type, text, caption, buttonYes, buttonNo, dontAskAgainName );
00397     if ( me && d->connection ) // Don't do anything if deleted meanwhile
00398     {
00399         d->connection->resume();
00400         kDebug(7007) << this << " SlaveInterface result=" << result;
00401         stream << result;
00402         d->connection->sendnow( CMD_MESSAGEBOXANSWER, packedArgs );
00403     }
00404 }
00405 
00406 int SlaveInterfacePrivate::messageBox(int type, const QString &text,
00407                                       const QString &caption, const QString &buttonYes,
00408                                       const QString &buttonNo, const QString &dontAskAgainName)
00409 {
00410     kDebug() << type << text << "caption=" << caption;
00411     int result = -1;
00412     KConfig *config = new KConfig("kioslaverc");
00413     KMessageBox::setDontShowAskAgainConfig(config);
00414 
00415     switch (type) {
00416     case KIO::SlaveBase::QuestionYesNo:
00417         result = KMessageBox::questionYesNo(
00418                      0, text, caption, KGuiItem(buttonYes),
00419                      KGuiItem(buttonNo), dontAskAgainName);
00420         break;
00421     case KIO::SlaveBase::WarningYesNo:
00422         result = KMessageBox::warningYesNo(
00423                      0, text, caption, KGuiItem(buttonYes),
00424                      KGuiItem(buttonNo), dontAskAgainName);
00425         break;
00426     case KIO::SlaveBase::WarningContinueCancel:
00427         result = KMessageBox::warningContinueCancel(
00428                      0, text, caption, KGuiItem(buttonYes),
00429                      KStandardGuiItem::cancel(), dontAskAgainName);
00430         break;
00431     case KIO::SlaveBase::WarningYesNoCancel:
00432         result = KMessageBox::warningYesNoCancel(
00433                      0, text, caption, KGuiItem(buttonYes), KGuiItem(buttonNo),
00434                      KStandardGuiItem::cancel(), dontAskAgainName);
00435         break;
00436     case KIO::SlaveBase::Information:
00437         KMessageBox::information(0, text, caption, dontAskAgainName);
00438         result = 1; // whatever
00439         break;
00440     case KIO::SlaveBase::SSLMessageBox:
00441     {
00442         KIO::MetaData meta = m_incomingMetaData;
00443         KSSLInfoDialog *kid = new KSSLInfoDialog(0);
00444         //### this is boilerplate code and appears in khtml_part.cpp almost unchanged!
00445         QStringList sl = meta["ssl_peer_chain"].split('\x01', QString::SkipEmptyParts);
00446         QList<QSslCertificate> certChain;
00447         bool decodedOk = true;
00448         foreach (const QString &s, sl) {
00449             certChain.append(QSslCertificate(s.toAscii())); //or is it toLocal8Bit or whatever?
00450             if (certChain.last().isNull()) {
00451                 decodedOk = false;
00452                 break;
00453             }
00454         }
00455 
00456         sl = meta["ssl_cert_errors"].split('\n', QString::SkipEmptyParts);
00457         QList<QSslError::SslError> errors;
00458         foreach (const QString &s, sl) {
00459             bool didConvert;
00460             QSslError::SslError error = static_cast<QSslError::SslError>(s.toInt(&didConvert));
00461             if (!didConvert) {
00462                 decodedOk = false;
00463                 break;
00464             }
00465             errors.append(error);
00466         }
00467 
00468         if (decodedOk || true/*H4X*/) {
00469             kid->setSslInfo(certChain,
00470                             meta["ssl_peer_ip"],
00471                             text, // the URL
00472                             meta["ssl_protocol_version"],
00473                             meta["ssl_cipher"],
00474                             meta["ssl_cipher_used_bits"].toInt(),
00475                             meta["ssl_cipher_bits"].toInt(),
00476                             errors);
00477             kDebug(7024) << "Showing SSL Info dialog";
00478             kid->exec();
00479             kDebug(7024) << "SSL Info dialog closed";
00480         } else {
00481             KMessageBox::information(0, i18n("The peer SSL certificate chain "
00482                                              "appears to be corrupt."),
00483                                      i18n("SSL"));
00484         }
00485         // KSSLInfoDialog deletes itself (Qt::WA_DeleteOnClose).
00486         result = 1; // whatever
00487         break;
00488     }
00489     default:
00490         kWarning() << "unknown type" << type;
00491         result = 0;
00492         break;
00493     }
00494     KMessageBox::setDontShowAskAgainConfig(0);
00495     delete config;
00496     return result;
00497 }
00498 
00499 #include "slaveinterface.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