• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

slaveinterface.cpp

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 "tdeio/slaveinterface.h"
00020 #include "tdeio/slavebase.h"
00021 #include "tdeio/connection.h"
00022 #include <errno.h>
00023 #include <assert.h>
00024 #include <kdebug.h>
00025 #include <stdlib.h>
00026 #include <sys/time.h>
00027 #include <unistd.h>
00028 #include <signal.h>
00029 #include <tdeio/observer.h>
00030 #include <tdeapplication.h>
00031 #include <dcopclient.h>
00032 #include <time.h>
00033 #include <tqtimer.h>
00034 
00035 using namespace TDEIO;
00036 
00037 
00038 TQDataStream &operator <<(TQDataStream &s, const TDEIO::UDSEntry &e )
00039 {
00040     // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front
00041     // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because
00042     // that would break the compatibility of the wire-protocol with KDE 2.
00043     // We do the same on 64-bit platforms in case we run in a mixed 32/64bit
00044     // environment.
00045 
00046     TQ_UINT32 size = 0;
00047     TDEIO::UDSEntry::ConstIterator it = e.begin();
00048     for( ; it != e.end(); ++it )
00049     {
00050        size++;
00051        if ((*it).m_uds == TDEIO::UDS_SIZE)
00052           size++;
00053     }
00054     s << size;
00055     it = e.begin();
00056     for( ; it != e.end(); ++it )
00057     {
00058        if ((*it).m_uds == TDEIO::UDS_SIZE)
00059        {
00060           TDEIO::UDSAtom a;
00061           a.m_uds = TDEIO::UDS_SIZE_LARGE;
00062           a.m_long = (*it).m_long >> 32;
00063           s << a;
00064        }
00065        s << *it;
00066     }
00067     return s;
00068 }
00069 
00070 TQDataStream &operator >>(TQDataStream &s, TDEIO::UDSEntry &e )
00071 {
00072     e.clear();
00073     TQ_UINT32 size;
00074     s >> size;
00075 
00076     // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front
00077     // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because
00078     // that would break the compatibility of the wire-protocol with KDE 2.
00079     // We do the same on 64-bit platforms in case we run in a mixed 32/64bit
00080     // environment.
00081     TQ_LLONG msb = 0;
00082     for(TQ_UINT32 i = 0; i < size; i++)
00083     {
00084        TDEIO::UDSAtom a;
00085        s >> a;
00086        if (a.m_uds == TDEIO::UDS_SIZE_LARGE)
00087        {
00088           msb = a.m_long;
00089        }
00090        else
00091        {
00092           if (a.m_uds == TDEIO::UDS_SIZE)
00093           {
00094              if (a.m_long < 0)
00095                 a.m_long += (TQ_LLONG) 1 << 32;
00096              a.m_long += msb << 32;
00097           }
00098           e.append(a);
00099           msb = 0;
00100        }
00101     }
00102     return s;
00103 }
00104 
00105 static const unsigned int max_nums = 8;
00106 
00107 class TDEIO::SlaveInterfacePrivate
00108 {
00109 public:
00110   SlaveInterfacePrivate() {
00111     slave_calcs_speed = false;
00112     start_time.tv_sec = 0;
00113     start_time.tv_usec = 0;
00114     last_time = 0;
00115     nums = 0;
00116     filesize = 0;
00117     offset = 0;
00118   }
00119   bool slave_calcs_speed;
00120   struct timeval start_time;
00121   uint nums;
00122   long times[max_nums];
00123   TDEIO::filesize_t sizes[max_nums];
00124   size_t last_time;
00125   TDEIO::filesize_t filesize, offset;
00126 
00127   TQTimer speed_timer;
00128 };
00129 
00131 
00132 SlaveInterface::SlaveInterface( Connection * connection )
00133 {
00134     m_pConnection = connection;
00135     m_progressId = 0;
00136 
00137     d = new SlaveInterfacePrivate;
00138     connect(&d->speed_timer, TQT_SIGNAL(timeout()), TQT_SLOT(calcSpeed()));
00139 }
00140 
00141 SlaveInterface::~SlaveInterface()
00142 {
00143     // Note: no kdDebug() here (scheduler is deleted very late)
00144     m_pConnection = 0; // a bit like the "wasDeleted" of TQObject...
00145 
00146     delete d;
00147 }
00148 
00149 static TDEIO::filesize_t readFilesize_t(TQDataStream &stream)
00150 {
00151    TDEIO::filesize_t result;
00152    unsigned long ul;
00153    stream >> ul;
00154    result = ul;
00155    if (stream.atEnd())
00156       return result;
00157    stream >> ul;
00158    result += ((TDEIO::filesize_t)ul) << 32;
00159    return result;
00160 }
00161 
00162 
00163 bool SlaveInterface::dispatch()
00164 {
00165     assert( m_pConnection );
00166 
00167     int cmd;
00168     TQByteArray data;
00169 
00170     if (m_pConnection->read( &cmd, data ) == -1)
00171       return false;
00172 
00173     return dispatch( cmd, data );
00174 }
00175 
00176 void SlaveInterface::calcSpeed()
00177 {
00178   if (d->slave_calcs_speed) {
00179     d->speed_timer.stop();
00180     return;
00181   }
00182 
00183   struct timeval tv;
00184   gettimeofday(&tv, 0);
00185 
00186   long diff = ((tv.tv_sec - d->start_time.tv_sec) * 1000000 +
00187            tv.tv_usec - d->start_time.tv_usec) / 1000;
00188   if (diff - d->last_time >= 900) {
00189     d->last_time = diff;
00190     if (d->nums == max_nums) {
00191       // let's hope gcc can optimize that well enough
00192       // otherwise I'd try memcpy :)
00193       for (unsigned int i = 1; i < max_nums; ++i) {
00194     d->times[i-1] = d->times[i];
00195     d->sizes[i-1] = d->sizes[i];
00196       }
00197       d->nums--;
00198     }
00199     d->times[d->nums] = diff;
00200     d->sizes[d->nums++] = d->filesize - d->offset;
00201 
00202     TDEIO::filesize_t lspeed = 1000 * (d->sizes[d->nums-1] - d->sizes[0]) / (d->times[d->nums-1] - d->times[0]);
00203 
00204 //     kdDebug() << "proceeed " << (long)d->filesize << " " << diff << " " 
00205 //        << long(d->sizes[d->nums-1] - d->sizes[0]) << " " 
00206 //        <<  d->times[d->nums-1] - d->times[0] << " " 
00207 //        << long(lspeed) << " " << double(d->filesize) / diff 
00208 //        << " " << convertSize(lspeed) << " " 
00209 //        << convertSize(long(double(d->filesize) / diff) * 1000) << " " 
00210 //        <<  endl ;
00211 
00212     if (!lspeed) {
00213       d->nums = 1;
00214       d->times[0] = diff;
00215       d->sizes[0] = d->filesize - d->offset;
00216     }
00217     emit speed(lspeed);
00218   }
00219 }
00220 
00221 bool SlaveInterface::dispatch( int _cmd, const TQByteArray &rawdata )
00222 {
00223     //kdDebug(7007) << "dispatch " << _cmd << endl;
00224 
00225     TQDataStream stream( rawdata, IO_ReadOnly );
00226 
00227     TQString str1;
00228     TQ_INT32 i;
00229     TQ_INT8 b;
00230     TQ_UINT32 ul;
00231 
00232     switch( _cmd ) {
00233     case MSG_DATA:
00234     emit data( rawdata );
00235     break;
00236     case MSG_DATA_REQ:
00237         emit dataReq();
00238     break;
00239     case MSG_FINISHED:
00240     //kdDebug(7007) << "Finished [this = " << this << "]" << endl;
00241         d->offset = 0;
00242         d->speed_timer.stop();
00243     emit finished();
00244     break;
00245     case MSG_STAT_ENTRY:
00246     {
00247         UDSEntry entry;
00248         stream >> entry;
00249         emit statEntry(entry);
00250     }
00251     break;
00252     case MSG_LIST_ENTRIES:
00253     {
00254         TQ_UINT32 count;
00255         stream >> count;
00256 
00257         UDSEntryList list;
00258         UDSEntry entry;
00259         for (uint i = 0; i < count; i++) {
00260         stream >> entry;
00261         list.append(entry);
00262         }
00263         emit listEntries(list);
00264 
00265     }
00266     break;
00267     case MSG_RESUME: // From the put job
00268     {
00269         d->offset = readFilesize_t(stream);
00270         emit canResume( d->offset );
00271     }
00272     break;
00273     case MSG_CANRESUME: // From the get job
00274         d->filesize = d->offset;
00275         emit canResume(0); // the arg doesn't matter
00276         break;
00277     case MSG_ERROR:
00278     stream >> i >> str1;
00279     kdDebug(7007) << "error " << i << " " << str1 << endl;
00280     emit error( i, str1 );
00281     break;
00282     case MSG_SLAVE_STATUS:
00283         {
00284            pid_t pid;
00285            TQCString protocol;
00286            stream >> pid >> protocol >> str1 >> b;
00287            emit slaveStatus(pid, protocol, str1, (b != 0));
00288         }
00289         break;
00290     case MSG_CONNECTED:
00291     emit connected();
00292     break;
00293 
00294     case INF_TOTAL_SIZE:
00295     {
00296         TDEIO::filesize_t size = readFilesize_t(stream);
00297         gettimeofday(&d->start_time, 0);
00298         d->last_time = 0;
00299         d->filesize = d->offset;
00300         d->sizes[0] = d->filesize - d->offset;
00301         d->times[0] = 0;
00302         d->nums = 1;
00303         d->speed_timer.start(1000);
00304         d->slave_calcs_speed = false;
00305         emit totalSize( size );
00306     }
00307     break;
00308     case INF_PROCESSED_SIZE:
00309     {
00310         TDEIO::filesize_t size = readFilesize_t(stream);
00311         emit processedSize( size );
00312         d->filesize = size;
00313     }
00314     break;
00315     case INF_SPEED:
00316     stream >> ul;
00317     d->slave_calcs_speed = true;
00318     d->speed_timer.stop();
00319 
00320     emit speed( ul );
00321     break;
00322     case INF_GETTING_FILE:
00323     break;
00324     case INF_ERROR_PAGE:
00325     emit errorPage();
00326     break;
00327     case INF_REDIRECTION:
00328       {
00329     KURL url;
00330     stream >> url;
00331 
00332     emit redirection( url );
00333       }
00334       break;
00335     case INF_MIME_TYPE:
00336     stream >> str1;
00337 
00338     emit mimeType( str1 );
00339         if (!m_pConnection->suspended())
00340             m_pConnection->sendnow( CMD_NONE, TQByteArray() );
00341     break;
00342     case INF_WARNING:
00343     stream >> str1;
00344 
00345     emit warning( str1 );
00346     break;
00347     case INF_NEED_PASSWD: {
00348         AuthInfo info;
00349         stream >> info;
00350     openPassDlg( info );
00351     break;
00352     }
00353     case INF_MESSAGEBOX: {
00354     kdDebug(7007) << "needs a msg box" << endl;
00355     TQString text, caption, buttonYes, buttonNo, dontAskAgainName;
00356         int type;
00357     stream >> type >> text >> caption >> buttonYes >> buttonNo;
00358     if (stream.atEnd())
00359     messageBox(type, text, caption, buttonYes, buttonNo);
00360     else {
00361         stream >> dontAskAgainName;
00362         messageBox(type, text, caption, buttonYes, buttonNo, dontAskAgainName);
00363     }
00364     break;
00365     }
00366     case INF_INFOMESSAGE: {
00367         TQString msg;
00368         stream >> msg;
00369         infoMessage(msg);
00370         break;
00371     }
00372     case INF_META_DATA: {
00373         MetaData meta_data;
00374         stream >> meta_data;
00375         metaData(meta_data);
00376         break;
00377     }
00378     case INF_LOCALURL: {
00379         TQ_INT8 islocal;
00380         KURL url;
00381         stream >> islocal >> url;
00382         emit localURL( url, islocal );
00383         break;
00384     }
00385     case MSG_NET_REQUEST: {
00386         TQString host;
00387     TQString slaveid;
00388         stream >> host >> slaveid;
00389         requestNetwork(host, slaveid);
00390         break;
00391     }
00392     case MSG_NET_DROP: {
00393         TQString host;
00394     TQString slaveid;
00395         stream >> host >> slaveid;
00396         dropNetwork(host, slaveid);
00397         break;
00398     }
00399     case MSG_NEED_SUBURL_DATA: {
00400         emit needSubURLData();
00401         break;
00402     }
00403     case MSG_AUTH_KEY: {
00404         bool keep;
00405         TQCString key, group;
00406         stream >> key >> group >> keep;
00407         kdDebug(7007) << "Got auth-key:      " << key << endl
00408                       << "    group-key:     " << group << endl
00409                       << "    keep password: " << keep << endl;
00410         emit authorizationKey( key, group, keep );
00411         break;
00412     }
00413     case MSG_DEL_AUTH_KEY: {
00414         TQCString key;
00415         stream >> key;
00416         kdDebug(7007) << "Delete auth-key: " << key << endl;
00417         emit delAuthorization( key );
00418     }
00419     default:
00420         kdWarning(7007) << "Slave sends unknown command (" << _cmd << "), dropping slave" << endl;
00421     return false;
00422     }
00423     return true;
00424 }
00425 
00426 void SlaveInterface::setOffset( TDEIO::filesize_t o)
00427 {
00428     d->offset = o;
00429 }
00430 
00431 TDEIO::filesize_t SlaveInterface::offset() const { return d->offset; }
00432 
00433 void SlaveInterface::requestNetwork(const TQString &host, const TQString &slaveid)
00434 {
00435     kdDebug(7007) << "requestNetwork " << host << slaveid << endl;
00436     TQByteArray packedArgs;
00437     TQDataStream stream( packedArgs, IO_WriteOnly );
00438     stream << true;
00439     m_pConnection->sendnow( INF_NETWORK_STATUS, packedArgs );
00440 }
00441 
00442 void SlaveInterface::dropNetwork(const TQString &host, const TQString &slaveid)
00443 {
00444     kdDebug(7007) << "dropNetwork " << host << slaveid << endl;
00445 }
00446 
00447 void SlaveInterface::sendResumeAnswer( bool resume )
00448 {
00449     kdDebug(7007) << "SlaveInterface::sendResumeAnswer ok for resuming :" << resume << endl;
00450     m_pConnection->sendnow( resume ? CMD_RESUMEANSWER : CMD_NONE, TQByteArray() );
00451 }
00452 
00453 void SlaveInterface::openPassDlg( const TQString& prompt, const TQString& user, bool readOnly )
00454 {
00455     AuthInfo info;
00456     info.prompt = prompt;
00457     info.username = user;
00458     info.readOnly = readOnly;
00459     openPassDlg( info );
00460 }
00461 
00462 void SlaveInterface::openPassDlg( const TQString& prompt, const TQString& user,
00463                                   const TQString& caption, const TQString& comment,
00464                                   const TQString& label, bool readOnly )
00465 {
00466     AuthInfo info;
00467     info.prompt = prompt;
00468     info.username = user;
00469     info.caption = caption;
00470     info.comment = comment;
00471     info.commentLabel = label;
00472     info.readOnly = readOnly;
00473     openPassDlg( info );
00474 }
00475 
00476 void SlaveInterface::openPassDlg( AuthInfo& info )
00477 {
00478     kdDebug(7007) << "SlaveInterface::openPassDlg: "
00479                   << "User= " << info.username
00480                   << ", Message= " << info.prompt << endl;
00481     bool result = Observer::self()->openPassDlg( info );
00482     if ( m_pConnection )
00483     {
00484         TQByteArray data;
00485         TQDataStream stream( data, IO_WriteOnly );
00486         if ( result )
00487         {
00488             stream << info;
00489             kdDebug(7007) << "SlaveInterface:::openPassDlg got: "
00490                           << "User= " << info.username
00491                           << ", Password= [hidden]" << endl;
00492             m_pConnection->sendnow( CMD_USERPASS, data );
00493         }
00494         else
00495             m_pConnection->sendnow( CMD_NONE, data );
00496     }
00497 }
00498 
00499 void SlaveInterface::messageBox( int type, const TQString &text, const TQString &_caption,
00500                                  const TQString &buttonYes, const TQString &buttonNo )
00501 {
00502     messageBox( type, text, _caption, buttonYes, buttonNo, TQString::null );
00503 }
00504 
00505 void SlaveInterface::messageBox( int type, const TQString &text, const TQString &_caption,
00506                                  const TQString &buttonYes, const TQString &buttonNo, const TQString &dontAskAgainName )
00507 {
00508     kdDebug(7007) << "messageBox " << type << " " << text << " - " << _caption << " " << dontAskAgainName << endl;
00509     TQByteArray packedArgs;
00510     TQDataStream stream( packedArgs, IO_WriteOnly );
00511 
00512     TQString caption( _caption );
00513     if ( type == TDEIO::SlaveBase::SSLMessageBox )
00514         caption = TQString::fromUtf8(kapp->dcopClient()->appId()); // hack, see observer.cpp
00515 
00516     emit needProgressId();
00517     kdDebug(7007) << "SlaveInterface::messageBox m_progressId=" << m_progressId << endl;
00518     TQGuardedPtr<SlaveInterface> me = this;
00519     m_pConnection->suspend();
00520     int result = Observer::/*self()->*/messageBox( m_progressId, type, text, caption, buttonYes, buttonNo, dontAskAgainName );
00521     if ( me && m_pConnection ) // Don't do anything if deleted meanwhile
00522     {
00523         m_pConnection->resume();
00524         kdDebug(7007) << this << " SlaveInterface result=" << result << endl;
00525         stream << result;
00526         m_pConnection->sendnow( CMD_MESSAGEBOXANSWER, packedArgs );
00527     }
00528 }
00529 
00530 // No longer used.
00531 // Remove in KDE 4.0
00532 void SlaveInterface::sigpipe_handler(int)
00533 {
00534     int saved_errno = errno;
00535     // Using kdDebug from a signal handler is not a good idea.
00536 #ifndef NDEBUG
00537     char msg[1000];
00538     sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid());
00539     if (write(2, msg, strlen(msg)) < 0) {
00540         // FIXME
00541         // Could not write error message
00542         // Triple fault? ;-)
00543     }
00544 #endif
00545 
00546     // Do nothing.
00547     // dispatch will return false and that will trigger ERR_SLAVE_DIED in slave.cpp
00548     errno = saved_errno;
00549 }
00550 
00551 void SlaveInterface::virtual_hook( int, void* )
00552 { /*BASE::virtual_hook( id, data );*/ }
00553 
00554 #include "slaveinterface.moc"

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.6.3
This website is maintained by Timothy Pearson.