• 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
35using namespace TDEIO;
36
37
38TQDataStream &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
70TQDataStream &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
105static const unsigned int max_nums = 8;
106
107class TDEIO::SlaveInterfacePrivate
108{
109public:
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
132SlaveInterface::SlaveInterface( Connection * connection )
133{
134 m_pConnection = connection;
135 m_progressId = 0;
136
137 d = new SlaveInterfacePrivate;
138 connect(&d->speed_timer, TQ_SIGNAL(timeout()), TQ_SLOT(calcSpeed()));
139}
140
141SlaveInterface::~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
149static 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
163bool 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
176void 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
221bool 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
426void SlaveInterface::setOffset( TDEIO::filesize_t o)
427{
428 d->offset = o;
429}
430
431TDEIO::filesize_t SlaveInterface::offset() const { return d->offset; }
432
433void 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
442void SlaveInterface::dropNetwork(const TQString &host, const TQString &slaveid)
443{
444 kdDebug(7007) << "dropNetwork " << host << slaveid << endl;
445}
446
447void 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
453void 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
462void 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
476void 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
499void 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
505void 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
532void 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
551void SlaveInterface::virtual_hook( int, void* )
552{ /*BASE::virtual_hook( id, data );*/ }
553
554#include "slaveinterface.moc"
Observer
Observer for TDEIO::Job progress information.
Definition: observer.h:55
Observer::openPassDlg
bool openPassDlg(const TQString &prompt, TQString &user, TQString &pass, bool readOnly)
Definition: observer.cpp:221
Observer::self
static Observer * self()
Returns the unique observer object.
Definition: observer.h:66
TDEIO::AuthInfo
This class is intended to make it easier to prompt for, cache and retrieve authorization information.
Definition: authinfo.h:52
TDEIO::AuthInfo::username
TQString username
This is required for caching.
Definition: authinfo.h:99
TDEIO::AuthInfo::prompt
TQString prompt
Information to be displayed when prompting the user for authentication information.
Definition: authinfo.h:115
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::AuthInfo::comment
TQString comment
Additional comment to be displayed when prompting the user for authentication information.
Definition: authinfo.h:150
TDEIO::AuthInfo::caption
TQString caption
The text to displayed in the title bar of the password prompting dialog.
Definition: authinfo.h:126
TDEIO::AuthInfo::readOnly
bool readOnly
Flag which if set forces the username field to be read-only.
Definition: authinfo.h:207
TDEIO::Connection
This class provides a simple means for IPC between two applications via a pipe.
Definition: connection.h:49
TDEIO::Connection::resume
void resume()
Resume handling of incoming data.
Definition: connection.cpp:79
TDEIO::Connection::suspend
void suspend()
Don't handle incoming data until resumed.
Definition: connection.cpp:72
TDEIO::Connection::read
int read(int *_cmd, TQByteArray &data)
Receive data.
Definition: connection.cpp:216
TDEIO::Connection::suspended
bool suspended() const
Definition: connection.h:134
TDEIO::Connection::sendnow
bool sendnow(int _cmd, const TQByteArray &data)
Sends the given command immediately.
Definition: connection.cpp:182
TDEIO::MetaData
MetaData is a simple map of key/value strings.
Definition: global.h:516
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::SlaveInterface::delAuthorization
void delAuthorization(const TQCString &grpkey)
TDEIO::SlaveInterface::authorizationKey
void authorizationKey(const TQCString &, const TQCString &, bool)
TDEIO::SlaveInterface::openPassDlg
void openPassDlg(TDEIO::AuthInfo &info)
Prompt the user for authrization info (login & password).
Definition: slaveinterface.cpp:476
TDEIO
A namespace for TDEIO globals.
Definition: authinfo.h:29
TDEIO::UDS_SIZE
@ UDS_SIZE
Size of the file.
Definition: global.h:319
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::filesize_t
TQ_ULLONG filesize_t
64-bit file size
Definition: global.h:39

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.9.4
This website is maintained by Timothy Pearson.