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

tdeio/tdeio

  • tdeio
  • tdeio
slaveinterface.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2000 David Faure <faure@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 */
18 
19 #include "tdeio/slaveinterface.h"
20 #include "tdeio/slavebase.h"
21 #include "tdeio/connection.h"
22 #include <errno.h>
23 #include <assert.h>
24 #include <kdebug.h>
25 #include <stdlib.h>
26 #include <sys/time.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <tdeio/observer.h>
30 #include <tdeapplication.h>
31 #include <dcopclient.h>
32 #include <time.h>
33 #include <tqtimer.h>
34 
35 using namespace TDEIO;
36 
37 
38 TQDataStream &operator <<(TQDataStream &s, const TDEIO::UDSEntry &e )
39 {
40  // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front
41  // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because
42  // that would break the compatibility of the wire-protocol with KDE 2.
43  // We do the same on 64-bit platforms in case we run in a mixed 32/64bit
44  // environment.
45 
46  TQ_UINT32 size = 0;
47  TDEIO::UDSEntry::ConstIterator it = e.begin();
48  for( ; it != e.end(); ++it )
49  {
50  size++;
51  if ((*it).m_uds == TDEIO::UDS_SIZE)
52  size++;
53  }
54  s << size;
55  it = e.begin();
56  for( ; it != e.end(); ++it )
57  {
58  if ((*it).m_uds == TDEIO::UDS_SIZE)
59  {
60  TDEIO::UDSAtom a;
61  a.m_uds = TDEIO::UDS_SIZE_LARGE;
62  a.m_long = (*it).m_long >> 32;
63  s << a;
64  }
65  s << *it;
66  }
67  return s;
68 }
69 
70 TQDataStream &operator >>(TQDataStream &s, TDEIO::UDSEntry &e )
71 {
72  e.clear();
73  TQ_UINT32 size;
74  s >> size;
75 
76  // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front
77  // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because
78  // that would break the compatibility of the wire-protocol with KDE 2.
79  // We do the same on 64-bit platforms in case we run in a mixed 32/64bit
80  // environment.
81  TQ_LLONG msb = 0;
82  for(TQ_UINT32 i = 0; i < size; i++)
83  {
84  TDEIO::UDSAtom a;
85  s >> a;
86  if (a.m_uds == TDEIO::UDS_SIZE_LARGE)
87  {
88  msb = a.m_long;
89  }
90  else
91  {
92  if (a.m_uds == TDEIO::UDS_SIZE)
93  {
94  if (a.m_long < 0)
95  a.m_long += (TQ_LLONG) 1 << 32;
96  a.m_long += msb << 32;
97  }
98  e.append(a);
99  msb = 0;
100  }
101  }
102  return s;
103 }
104 
105 static const unsigned int max_nums = 8;
106 
107 class TDEIO::SlaveInterfacePrivate
108 {
109 public:
110  SlaveInterfacePrivate() {
111  slave_calcs_speed = false;
112  start_time.tv_sec = 0;
113  start_time.tv_usec = 0;
114  last_time = 0;
115  nums = 0;
116  filesize = 0;
117  offset = 0;
118  }
119  bool slave_calcs_speed;
120  struct timeval start_time;
121  uint nums;
122  long times[max_nums];
123  TDEIO::filesize_t sizes[max_nums];
124  size_t last_time;
125  TDEIO::filesize_t filesize, offset;
126 
127  TQTimer speed_timer;
128 };
129 
131 
132 SlaveInterface::SlaveInterface( Connection * connection )
133 {
134  m_pConnection = connection;
135  m_progressId = 0;
136 
137  d = new SlaveInterfacePrivate;
138  connect(&d->speed_timer, TQT_SIGNAL(timeout()), TQT_SLOT(calcSpeed()));
139 }
140 
141 SlaveInterface::~SlaveInterface()
142 {
143  // Note: no kdDebug() here (scheduler is deleted very late)
144  m_pConnection = 0; // a bit like the "wasDeleted" of TQObject...
145 
146  delete d;
147 }
148 
149 static TDEIO::filesize_t readFilesize_t(TQDataStream &stream)
150 {
151  TDEIO::filesize_t result;
152  unsigned long ul;
153  stream >> ul;
154  result = ul;
155  if (stream.atEnd())
156  return result;
157  stream >> ul;
158  result += ((TDEIO::filesize_t)ul) << 32;
159  return result;
160 }
161 
162 
163 bool SlaveInterface::dispatch()
164 {
165  assert( m_pConnection );
166 
167  int cmd;
168  TQByteArray data;
169 
170  if (m_pConnection->read( &cmd, data ) == -1)
171  return false;
172 
173  return dispatch( cmd, data );
174 }
175 
176 void SlaveInterface::calcSpeed()
177 {
178  if (d->slave_calcs_speed) {
179  d->speed_timer.stop();
180  return;
181  }
182 
183  struct timeval tv;
184  gettimeofday(&tv, 0);
185 
186  long diff = ((tv.tv_sec - d->start_time.tv_sec) * 1000000 +
187  tv.tv_usec - d->start_time.tv_usec) / 1000;
188  if (diff - d->last_time >= 900) {
189  d->last_time = diff;
190  if (d->nums == max_nums) {
191  // let's hope gcc can optimize that well enough
192  // otherwise I'd try memcpy :)
193  for (unsigned int i = 1; i < max_nums; ++i) {
194  d->times[i-1] = d->times[i];
195  d->sizes[i-1] = d->sizes[i];
196  }
197  d->nums--;
198  }
199  d->times[d->nums] = diff;
200  d->sizes[d->nums++] = d->filesize - d->offset;
201 
202  TDEIO::filesize_t lspeed = 1000 * (d->sizes[d->nums-1] - d->sizes[0]) / (d->times[d->nums-1] - d->times[0]);
203 
204 // kdDebug() << "proceeed " << (long)d->filesize << " " << diff << " "
205 // << long(d->sizes[d->nums-1] - d->sizes[0]) << " "
206 // << d->times[d->nums-1] - d->times[0] << " "
207 // << long(lspeed) << " " << double(d->filesize) / diff
208 // << " " << convertSize(lspeed) << " "
209 // << convertSize(long(double(d->filesize) / diff) * 1000) << " "
210 // << endl ;
211 
212  if (!lspeed) {
213  d->nums = 1;
214  d->times[0] = diff;
215  d->sizes[0] = d->filesize - d->offset;
216  }
217  emit speed(lspeed);
218  }
219 }
220 
221 bool SlaveInterface::dispatch( int _cmd, const TQByteArray &rawdata )
222 {
223  //kdDebug(7007) << "dispatch " << _cmd << endl;
224 
225  TQDataStream stream( rawdata, IO_ReadOnly );
226 
227  TQString str1;
228  TQ_INT32 i;
229  TQ_INT8 b;
230  TQ_UINT32 ul;
231 
232  switch( _cmd ) {
233  case MSG_DATA:
234  emit data( rawdata );
235  break;
236  case MSG_DATA_REQ:
237  emit dataReq();
238  break;
239  case MSG_FINISHED:
240  //kdDebug(7007) << "Finished [this = " << this << "]" << endl;
241  d->offset = 0;
242  d->speed_timer.stop();
243  emit finished();
244  break;
245  case MSG_STAT_ENTRY:
246  {
247  UDSEntry entry;
248  stream >> entry;
249  emit statEntry(entry);
250  }
251  break;
252  case MSG_LIST_ENTRIES:
253  {
254  TQ_UINT32 count;
255  stream >> count;
256 
257  UDSEntryList list;
258  UDSEntry entry;
259  for (uint i = 0; i < count; i++) {
260  stream >> entry;
261  list.append(entry);
262  }
263  emit listEntries(list);
264 
265  }
266  break;
267  case MSG_RESUME: // From the put job
268  {
269  d->offset = readFilesize_t(stream);
270  emit canResume( d->offset );
271  }
272  break;
273  case MSG_CANRESUME: // From the get job
274  d->filesize = d->offset;
275  emit canResume(0); // the arg doesn't matter
276  break;
277  case MSG_ERROR:
278  stream >> i >> str1;
279  kdDebug(7007) << "error " << i << " " << str1 << endl;
280  emit error( i, str1 );
281  break;
282  case MSG_SLAVE_STATUS:
283  {
284  pid_t pid;
285  TQCString protocol;
286  stream >> pid >> protocol >> str1 >> b;
287  emit slaveStatus(pid, protocol, str1, (b != 0));
288  }
289  break;
290  case MSG_CONNECTED:
291  emit connected();
292  break;
293 
294  case INF_TOTAL_SIZE:
295  {
296  TDEIO::filesize_t size = readFilesize_t(stream);
297  gettimeofday(&d->start_time, 0);
298  d->last_time = 0;
299  d->filesize = d->offset;
300  d->sizes[0] = d->filesize - d->offset;
301  d->times[0] = 0;
302  d->nums = 1;
303  d->speed_timer.start(1000);
304  d->slave_calcs_speed = false;
305  emit totalSize( size );
306  }
307  break;
308  case INF_PROCESSED_SIZE:
309  {
310  TDEIO::filesize_t size = readFilesize_t(stream);
311  emit processedSize( size );
312  d->filesize = size;
313  }
314  break;
315  case INF_SPEED:
316  stream >> ul;
317  d->slave_calcs_speed = true;
318  d->speed_timer.stop();
319 
320  emit speed( ul );
321  break;
322  case INF_GETTING_FILE:
323  break;
324  case INF_ERROR_PAGE:
325  emit errorPage();
326  break;
327  case INF_REDIRECTION:
328  {
329  KURL url;
330  stream >> url;
331 
332  emit redirection( url );
333  }
334  break;
335  case INF_MIME_TYPE:
336  stream >> str1;
337 
338  emit mimeType( str1 );
339  if (!m_pConnection->suspended())
340  m_pConnection->sendnow( CMD_NONE, TQByteArray() );
341  break;
342  case INF_WARNING:
343  stream >> str1;
344 
345  emit warning( str1 );
346  break;
347  case INF_NEED_PASSWD: {
348  AuthInfo info;
349  stream >> info;
350  openPassDlg( info );
351  break;
352  }
353  case INF_MESSAGEBOX: {
354  kdDebug(7007) << "needs a msg box" << endl;
355  TQString text, caption, buttonYes, buttonNo, dontAskAgainName;
356  int type;
357  stream >> type >> text >> caption >> buttonYes >> buttonNo;
358  if (stream.atEnd())
359  messageBox(type, text, caption, buttonYes, buttonNo);
360  else {
361  stream >> dontAskAgainName;
362  messageBox(type, text, caption, buttonYes, buttonNo, dontAskAgainName);
363  }
364  break;
365  }
366  case INF_INFOMESSAGE: {
367  TQString msg;
368  stream >> msg;
369  infoMessage(msg);
370  break;
371  }
372  case INF_META_DATA: {
373  MetaData meta_data;
374  stream >> meta_data;
375  metaData(meta_data);
376  break;
377  }
378  case INF_LOCALURL: {
379  TQ_INT8 islocal;
380  KURL url;
381  stream >> islocal >> url;
382  emit localURL( url, islocal );
383  break;
384  }
385  case MSG_NET_REQUEST: {
386  TQString host;
387  TQString slaveid;
388  stream >> host >> slaveid;
389  requestNetwork(host, slaveid);
390  break;
391  }
392  case MSG_NET_DROP: {
393  TQString host;
394  TQString slaveid;
395  stream >> host >> slaveid;
396  dropNetwork(host, slaveid);
397  break;
398  }
399  case MSG_NEED_SUBURL_DATA: {
400  emit needSubURLData();
401  break;
402  }
403  case MSG_AUTH_KEY: {
404  bool keep;
405  TQCString key, group;
406  stream >> key >> group >> keep;
407  kdDebug(7007) << "Got auth-key: " << key << endl
408  << " group-key: " << group << endl
409  << " keep password: " << keep << endl;
410  emit authorizationKey( key, group, keep );
411  break;
412  }
413  case MSG_DEL_AUTH_KEY: {
414  TQCString key;
415  stream >> key;
416  kdDebug(7007) << "Delete auth-key: " << key << endl;
417  emit delAuthorization( key );
418  }
419  default:
420  kdWarning(7007) << "Slave sends unknown command (" << _cmd << "), dropping slave" << endl;
421  return false;
422  }
423  return true;
424 }
425 
426 void SlaveInterface::setOffset( TDEIO::filesize_t o)
427 {
428  d->offset = o;
429 }
430 
431 TDEIO::filesize_t SlaveInterface::offset() const { return d->offset; }
432 
433 void SlaveInterface::requestNetwork(const TQString &host, const TQString &slaveid)
434 {
435  kdDebug(7007) << "requestNetwork " << host << slaveid << endl;
436  TQByteArray packedArgs;
437  TQDataStream stream( packedArgs, IO_WriteOnly );
438  stream << true;
439  m_pConnection->sendnow( INF_NETWORK_STATUS, packedArgs );
440 }
441 
442 void SlaveInterface::dropNetwork(const TQString &host, const TQString &slaveid)
443 {
444  kdDebug(7007) << "dropNetwork " << host << slaveid << endl;
445 }
446 
447 void SlaveInterface::sendResumeAnswer( bool resume )
448 {
449  kdDebug(7007) << "SlaveInterface::sendResumeAnswer ok for resuming :" << resume << endl;
450  m_pConnection->sendnow( resume ? CMD_RESUMEANSWER : CMD_NONE, TQByteArray() );
451 }
452 
453 void SlaveInterface::openPassDlg( const TQString& prompt, const TQString& user, bool readOnly )
454 {
455  AuthInfo info;
456  info.prompt = prompt;
457  info.username = user;
458  info.readOnly = readOnly;
459  openPassDlg( info );
460 }
461 
462 void SlaveInterface::openPassDlg( const TQString& prompt, const TQString& user,
463  const TQString& caption, const TQString& comment,
464  const TQString& label, bool readOnly )
465 {
466  AuthInfo info;
467  info.prompt = prompt;
468  info.username = user;
469  info.caption = caption;
470  info.comment = comment;
471  info.commentLabel = label;
472  info.readOnly = readOnly;
473  openPassDlg( info );
474 }
475 
476 void SlaveInterface::openPassDlg( AuthInfo& info )
477 {
478  kdDebug(7007) << "SlaveInterface::openPassDlg: "
479  << "User= " << info.username
480  << ", Message= " << info.prompt << endl;
481  bool result = Observer::self()->openPassDlg( info );
482  if ( m_pConnection )
483  {
484  TQByteArray data;
485  TQDataStream stream( data, IO_WriteOnly );
486  if ( result )
487  {
488  stream << info;
489  kdDebug(7007) << "SlaveInterface:::openPassDlg got: "
490  << "User= " << info.username
491  << ", Password= [hidden]" << endl;
492  m_pConnection->sendnow( CMD_USERPASS, data );
493  }
494  else
495  m_pConnection->sendnow( CMD_NONE, data );
496  }
497 }
498 
499 void SlaveInterface::messageBox( int type, const TQString &text, const TQString &_caption,
500  const TQString &buttonYes, const TQString &buttonNo )
501 {
502  messageBox( type, text, _caption, buttonYes, buttonNo, TQString::null );
503 }
504 
505 void SlaveInterface::messageBox( int type, const TQString &text, const TQString &_caption,
506  const TQString &buttonYes, const TQString &buttonNo, const TQString &dontAskAgainName )
507 {
508  kdDebug(7007) << "messageBox " << type << " " << text << " - " << _caption << " " << dontAskAgainName << endl;
509  TQByteArray packedArgs;
510  TQDataStream stream( packedArgs, IO_WriteOnly );
511 
512  TQString caption( _caption );
513  if ( type == TDEIO::SlaveBase::SSLMessageBox )
514  caption = TQString::fromUtf8(kapp->dcopClient()->appId()); // hack, see observer.cpp
515 
516  emit needProgressId();
517  kdDebug(7007) << "SlaveInterface::messageBox m_progressId=" << m_progressId << endl;
518  TQGuardedPtr<SlaveInterface> me = this;
519  m_pConnection->suspend();
520  int result = Observer::/*self()->*/messageBox( m_progressId, type, text, caption, buttonYes, buttonNo, dontAskAgainName );
521  if ( me && m_pConnection ) // Don't do anything if deleted meanwhile
522  {
523  m_pConnection->resume();
524  kdDebug(7007) << this << " SlaveInterface result=" << result << endl;
525  stream << result;
526  m_pConnection->sendnow( CMD_MESSAGEBOXANSWER, packedArgs );
527  }
528 }
529 
530 // No longer used.
531 // Remove in KDE 4.0
532 void SlaveInterface::sigpipe_handler(int)
533 {
534  int saved_errno = errno;
535  // Using kdDebug from a signal handler is not a good idea.
536 #ifndef NDEBUG
537  char msg[1000];
538  sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid());
539  if (write(2, msg, strlen(msg)) < 0) {
540  // FIXME
541  // Could not write error message
542  // Triple fault? ;-)
543  }
544 #endif
545 
546  // Do nothing.
547  // dispatch will return false and that will trigger ERR_SLAVE_DIED in slave.cpp
548  errno = saved_errno;
549 }
550 
551 void SlaveInterface::virtual_hook( int, void* )
552 { /*BASE::virtual_hook( id, data );*/ }
553 
554 #include "slaveinterface.moc"
TDEIO::UDSEntry
TQValueList< UDSAtom > UDSEntry
An entry is the list of atoms containing all the information for a file or URL.
Definition: global.h:507
TDEIO::SlaveInterface::delAuthorization
void delAuthorization(const TQCString &grpkey)
TDEIO::filesize_t
TQ_ULLONG filesize_t
64-bit file size
Definition: global.h:39
TDEIO::AuthInfo::username
TQString username
This is required for caching.
Definition: authinfo.h:99
TDEIO::Connection::sendnow
bool sendnow(int _cmd, const TQByteArray &data)
Sends the given command immediately.
Definition: connection.cpp:182
TDEIO::AuthInfo::readOnly
bool readOnly
Flag which if set forces the username field to be read-only.
Definition: authinfo.h:207
TDEIO
A namespace for TDEIO globals.
Definition: authinfo.h:29
TDEIO::AuthInfo::commentLabel
TQString commentLabel
Descriptive label to be displayed in front of the comment when prompting the user for password...
Definition: authinfo.h:159
TDEIO::Connection::suspended
bool suspended() const
Returns status of connection.
Definition: connection.h:134
TDEIO::Connection::read
int read(int *_cmd, TQByteArray &data)
Receive data.
Definition: connection.cpp:216
TDEIO::Connection::suspend
void suspend()
Don't handle incoming data until resumed.
Definition: connection.cpp:72
Observer::openPassDlg
bool openPassDlg(const TQString &prompt, TQString &user, TQString &pass, bool readOnly)
Definition: observer.cpp:221
Observer
Observer for TDEIO::Job progress information.
Definition: observer.h:55
TDEIO::Connection
This class provides a simple means for IPC between two applications via a pipe.
Definition: connection.h:48
TDEIO::SlaveInterface::openPassDlg
void openPassDlg(TDEIO::AuthInfo &info)
Prompt the user for authrization info (login & password).
Definition: slaveinterface.cpp:476
TDEIO::AuthInfo
This class is intended to make it easier to prompt for, cache and retrieve authorization information...
Definition: authinfo.h:51
TDEIO::AuthInfo::prompt
TQString prompt
Information to be displayed when prompting the user for authentication information.
Definition: authinfo.h:115
TDEIO::AuthInfo::caption
TQString caption
The text to displayed in the title bar of the password prompting dialog.
Definition: authinfo.h:126
TDEIO::SlaveInterface::sendResumeAnswer
void sendResumeAnswer(bool resume)
Send our answer to the MSG_RESUME (canResume) request (to tell the "put" job whether to resume or not...
Definition: slaveinterface.cpp:447
TDEIO::UDS_SIZE
Size of the file.
Definition: global.h:319
TDEIO::SlaveInterface::authorizationKey
void authorizationKey(const TQCString &, const TQCString &, bool)
Observer::self
static Observer * self()
Returns the unique observer object.
Definition: observer.h:66
TDEIO::AuthInfo::comment
TQString comment
Additional comment to be displayed when prompting the user for authentication information.
Definition: authinfo.h:150
TDEIO::MetaData
MetaData is a simple map of key/value strings.
Definition: global.h:515
TDEIO::Connection::resume
void resume()
Resume handling of incoming data.
Definition: connection.cpp:79

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.8.8
This website is maintained by Timothy Pearson.