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