-rw-r--r-- | core/launcher/documentlist.cpp | 8 | ||||
-rw-r--r-- | core/launcher/qprocess_unix.cpp | 646 | ||||
-rw-r--r-- | core/launcher/screensaver.cpp | 386 | ||||
-rw-r--r-- | core/launcher/server.cpp | 434 | ||||
-rw-r--r-- | core/launcher/transferserver.cpp | 851 |
5 files changed, 1164 insertions, 1161 deletions
diff --git a/core/launcher/documentlist.cpp b/core/launcher/documentlist.cpp index 19ceb0f..44ceb0c 100644 --- a/core/launcher/documentlist.cpp +++ b/core/launcher/documentlist.cpp | |||
@@ -342,135 +342,135 @@ void DocumentList::DiffAppLnks() | |||
342 | if ( d->sendAppLnks && d->serverGui ) { | 342 | if ( d->sendAppLnks && d->serverGui ) { |
343 | static QStringList prevTypeList = appLnkSet->types(); | 343 | static QStringList prevTypeList = appLnkSet->types(); |
344 | QStringList types = appLnkSet2->types(); | 344 | QStringList types = appLnkSet2->types(); |
345 | for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) { | 345 | for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) { |
346 | if ( !(*ittypes).isEmpty() ) { | 346 | if ( !(*ittypes).isEmpty() ) { |
347 | if ( !prevTypeList.contains(*ittypes) ) { | 347 | if ( !prevTypeList.contains(*ittypes) ) { |
348 | QString name = appLnkSet2->typeName(*ittypes); | 348 | QString name = appLnkSet2->typeName(*ittypes); |
349 | QPixmap pm = appLnkSet2->typePixmap(*ittypes); | 349 | QPixmap pm = appLnkSet2->typePixmap(*ittypes); |
350 | QPixmap bgPm = appLnkSet2->typeBigPixmap(*ittypes); | 350 | QPixmap bgPm = appLnkSet2->typeBigPixmap(*ittypes); |
351 | 351 | ||
352 | if (pm.isNull()) { | 352 | if (pm.isNull()) { |
353 | QImage img( Resource::loadImage( "UnknownDocument" ) ); | 353 | QImage img( Resource::loadImage( "UnknownDocument" ) ); |
354 | pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); | 354 | pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); |
355 | bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ); | 355 | bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ); |
356 | } | 356 | } |
357 | 357 | ||
358 | odebug << "adding type " << (*ittypes) << "" << oendl; | 358 | odebug << "adding type " << (*ittypes) << "" << oendl; |
359 | 359 | ||
360 | // ### our current launcher expects docs tab to be last | 360 | // ### our current launcher expects docs tab to be last |
361 | d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm ); | 361 | d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm ); |
362 | } | 362 | } |
363 | prevTypeList.remove(*ittypes); | 363 | prevTypeList.remove(*ittypes); |
364 | } | 364 | } |
365 | } | 365 | } |
366 | for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) { | 366 | for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) { |
367 | odebug << "removing type " << (*ittypes) << "" << oendl; | 367 | odebug << "removing type " << (*ittypes) << "" << oendl; |
368 | d->serverGui->typeRemoved(*ittypes); | 368 | d->serverGui->typeRemoved(*ittypes); |
369 | } | 369 | } |
370 | prevTypeList = types; | 370 | prevTypeList = types; |
371 | } | 371 | } |
372 | 372 | ||
373 | 373 | ||
374 | QListIterator<AppLnk> it1( appLnkSet->children() ); | 374 | QListIterator<AppLnk> it1( appLnkSet->children() ); |
375 | QListIterator<AppLnk> it2( appLnkSet2->children() ); | 375 | QListIterator<AppLnk> it2( appLnkSet2->children() ); |
376 | 376 | ||
377 | AppLnk *i; | 377 | AppLnk *i; |
378 | AppLnk *j; | 378 | AppLnk *j; |
379 | bool found; | 379 | bool found; |
380 | 380 | ||
381 | while ( (j=it2.current()) ) { | 381 | while ( (j=it2.current()) ) { |
382 | it1 = appLnkSet->children(); | 382 | it1 = appLnkSet->children(); |
383 | found = false; | 383 | found = false; |
384 | while ( (i=it1.current()) ){ | 384 | while ( (i=it1.current()) ){ |
385 | if (strcmp(i->name().ascii(),j->name().ascii()) == 0) | 385 | if (strcmp(i->name().ascii(),j->name().ascii()) == 0) |
386 | found = true; | 386 | found = true; |
387 | ++it1; | 387 | ++it1; |
388 | } | 388 | } |
389 | if (!found) { | 389 | if (!found) { |
390 | qDebug("Item %s needs to be added",j->name().ascii() ); | 390 | odebug << "Item " << j->name().ascii() << " needs to be added" << oendl; |
391 | d->serverGui->applicationAdded( j->type(), *j ); | 391 | d->serverGui->applicationAdded( j->type(), *j ); |
392 | } | 392 | } |
393 | ++it2; | 393 | ++it2; |
394 | } | 394 | } |
395 | 395 | ||
396 | it1 = appLnkSet->children(); | 396 | it1 = appLnkSet->children(); |
397 | while ( (i=it1.current()) ) { | 397 | while ( (i=it1.current()) ) { |
398 | it2 = appLnkSet2->children(); | 398 | it2 = appLnkSet2->children(); |
399 | found = false; | 399 | found = false; |
400 | while ( (j=it2.current()) ){ | 400 | while ( (j=it2.current()) ){ |
401 | if (strcmp(i->name().ascii(),j->name().ascii()) == 0) | 401 | if (strcmp(i->name().ascii(),j->name().ascii()) == 0) |
402 | found = true; | 402 | found = true; |
403 | ++it2; | 403 | ++it2; |
404 | } | 404 | } |
405 | if (!found) { | 405 | if (!found) { |
406 | qDebug("Item %s needs to be removed",i->name().ascii() ); | 406 | odebug << "Item " << i->name().ascii() << " needs to be removed" << oendl; |
407 | d->serverGui->applicationRemoved( i->type(), *i ); | 407 | d->serverGui->applicationRemoved( i->type(), *i ); |
408 | } | 408 | } |
409 | 409 | ||
410 | ++it1; | 410 | ++it1; |
411 | } | 411 | } |
412 | 412 | ||
413 | delete appLnkSet; | 413 | delete appLnkSet; |
414 | appLnkSet = appLnkSet2; | 414 | appLnkSet = appLnkSet2; |
415 | 415 | ||
416 | } | 416 | } |
417 | void DocumentList::storageChanged() | 417 | void DocumentList::storageChanged() |
418 | { | 418 | { |
419 | QTime t; | 419 | QTime t; |
420 | // ### can implement better | 420 | // ### can implement better |
421 | 421 | ||
422 | t.start(); | 422 | t.start(); |
423 | DiffAppLnks(); | 423 | DiffAppLnks(); |
424 | // reloadAppLnks(); | 424 | // reloadAppLnks(); |
425 | qDebug("Reload App links took %i ms",t.elapsed() ); | 425 | odebug << "Reload App links took " << t.elapsed() << " ms" << oendl; |
426 | reloadDocLnks(); | 426 | reloadDocLnks(); |
427 | // odebug << "Reload links took " << t.elapsed() << " ms " << oendl; | 427 | // odebug << "Reload links took " << t.elapsed() << " ms " << oendl; |
428 | qDebug("Reload All links took %i ms",t.elapsed() ); | 428 | odebug << "Reload All links took " << t.elapsed() << " ms" << oendl; |
429 | // ### Optimization opportunity | 429 | // ### Optimization opportunity |
430 | // Could be a bit more intelligent and somehow work out which | 430 | // Could be a bit more intelligent and somehow work out which |
431 | // mtab entry has changed and then only scan that and add and remove | 431 | // mtab entry has changed and then only scan that and add and remove |
432 | // links appropriately. | 432 | // links appropriately. |
433 | // rescan(); | 433 | // rescan(); |
434 | } | 434 | } |
435 | 435 | ||
436 | void DocumentList::sendAllDocLinks() | 436 | void DocumentList::sendAllDocLinks() |
437 | { | 437 | { |
438 | if ( d->tid != 0 ) { | 438 | if ( d->tid != 0 ) { |
439 | // We are in the middle of scanning, set a flag so | 439 | // We are in the middle of scanning, set a flag so |
440 | // we do this when we finish our scanning | 440 | // we do this when we finish our scanning |
441 | d->needToSendAllDocLinks = true; | 441 | d->needToSendAllDocLinks = true; |
442 | return; | 442 | return; |
443 | } | 443 | } |
444 | 444 | ||
445 | QString contents; | 445 | QString contents; |
446 | Categories cats; | 446 | Categories cats; |
447 | for ( QListIterator<DocLnk> it( d->dls.children() ); it.current(); ++it ) { | 447 | for ( QListIterator<DocLnk> it( d->dls.children() ); it.current(); ++it ) { |
448 | DocLnk *doc = it.current(); | 448 | DocLnk *doc = it.current(); |
449 | QFileInfo fi( doc->file() ); | 449 | QFileInfo fi( doc->file() ); |
450 | if ( !fi.exists() ) | 450 | if ( !fi.exists() ) |
451 | continue; | 451 | continue; |
452 | 452 | ||
453 | bool fake = !doc->linkFileKnown(); | 453 | bool fake = !doc->linkFileKnown(); |
454 | if ( !fake ) { | 454 | if ( !fake ) { |
455 | QFile f( doc->linkFile() ); | 455 | QFile f( doc->linkFile() ); |
456 | if ( f.open( IO_ReadOnly ) ) { | 456 | if ( f.open( IO_ReadOnly ) ) { |
457 | QTextStream ts( &f ); | 457 | QTextStream ts( &f ); |
458 | ts.setEncoding( QTextStream::UnicodeUTF8 ); | 458 | ts.setEncoding( QTextStream::UnicodeUTF8 ); |
459 | contents += ts.read(); | 459 | contents += ts.read(); |
460 | f.close(); | 460 | f.close(); |
461 | } else | 461 | } else |
462 | fake = TRUE; | 462 | fake = TRUE; |
463 | } | 463 | } |
464 | if (fake) { | 464 | if (fake) { |
465 | contents += "[Desktop Entry]\n"; // No tr | 465 | contents += "[Desktop Entry]\n"; // No tr |
466 | contents += "Categories = " + // No tr | 466 | contents += "Categories = " + // No tr |
467 | cats.labels("Document View",doc->categories()).join(";") + "\n"; // No tr | 467 | cats.labels("Document View",doc->categories()).join(";") + "\n"; // No tr |
468 | contents += "Name = "+doc->name()+"\n"; // No tr | 468 | contents += "Name = "+doc->name()+"\n"; // No tr |
469 | contents += "Type = "+doc->type()+"\n"; // No tr | 469 | contents += "Type = "+doc->type()+"\n"; // No tr |
470 | } | 470 | } |
471 | contents += "File = "+doc->file()+"\n"; // No tr // (resolves path) | 471 | contents += "File = "+doc->file()+"\n"; // No tr // (resolves path) |
472 | contents += QString("Size = %1\n").arg( fi.size() ); // No tr | 472 | contents += QString("Size = %1\n").arg( fi.size() ); // No tr |
473 | } | 473 | } |
474 | 474 | ||
475 | //odebug << "sending length " << contents.length() << "" << oendl; | 475 | //odebug << "sending length " << contents.length() << "" << oendl; |
476 | #ifndef QT_NO_COP | 476 | #ifndef QT_NO_COP |
diff --git a/core/launcher/qprocess_unix.cpp b/core/launcher/qprocess_unix.cpp index 56e1b1d..97c0460 100644 --- a/core/launcher/qprocess_unix.cpp +++ b/core/launcher/qprocess_unix.cpp | |||
@@ -88,1086 +88,1086 @@ class QProcessPrivate | |||
88 | { | 88 | { |
89 | public: | 89 | public: |
90 | QProcessPrivate(); | 90 | QProcessPrivate(); |
91 | ~QProcessPrivate(); | 91 | ~QProcessPrivate(); |
92 | 92 | ||
93 | void closeOpenSocketsForChild(); | 93 | void closeOpenSocketsForChild(); |
94 | void newProc( pid_t pid, QProcess *process ); | 94 | void newProc( pid_t pid, QProcess *process ); |
95 | 95 | ||
96 | QByteArray bufStdout; | 96 | QByteArray bufStdout; |
97 | QByteArray bufStderr; | 97 | QByteArray bufStderr; |
98 | 98 | ||
99 | QQueue<QByteArray> stdinBuf; | 99 | QQueue<QByteArray> stdinBuf; |
100 | 100 | ||
101 | QSocketNotifier *notifierStdin; | 101 | QSocketNotifier *notifierStdin; |
102 | QSocketNotifier *notifierStdout; | 102 | QSocketNotifier *notifierStdout; |
103 | QSocketNotifier *notifierStderr; | 103 | QSocketNotifier *notifierStderr; |
104 | 104 | ||
105 | ssize_t stdinBufRead; | 105 | ssize_t stdinBufRead; |
106 | QProc *proc; | 106 | QProc *proc; |
107 | 107 | ||
108 | bool exitValuesCalculated; | 108 | bool exitValuesCalculated; |
109 | bool socketReadCalled; | 109 | bool socketReadCalled; |
110 | 110 | ||
111 | static QProcessManager *procManager; | 111 | static QProcessManager *procManager; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | 114 | ||
115 | /*********************************************************************** | 115 | /*********************************************************************** |
116 | * | 116 | * |
117 | * QProc | 117 | * QProc |
118 | * | 118 | * |
119 | **********************************************************************/ | 119 | **********************************************************************/ |
120 | /* | 120 | /* |
121 | The class QProcess does not necessarily map exactly to the running | 121 | The class QProcess does not necessarily map exactly to the running |
122 | child processes: if the process is finished, the QProcess class may still be | 122 | child processes: if the process is finished, the QProcess class may still be |
123 | there; furthermore a user can use QProcess to start more than one process. | 123 | there; furthermore a user can use QProcess to start more than one process. |
124 | 124 | ||
125 | The helper-class QProc has the semantics that one instance of this class maps | 125 | The helper-class QProc has the semantics that one instance of this class maps |
126 | directly to a running child process. | 126 | directly to a running child process. |
127 | */ | 127 | */ |
128 | class QProc | 128 | class QProc |
129 | { | 129 | { |
130 | public: | 130 | public: |
131 | QProc( pid_t p, QProcess *proc=0 ) : pid(p), process(proc) | 131 | QProc( pid_t p, QProcess *proc=0 ) : pid(p), process(proc) |
132 | { | 132 | { |
133 | #if defined(QT_QPROCESS_DEBUG) | 133 | #if defined(QT_QPROCESS_DEBUG) |
134 | odebug << "QProc: Constructor for pid " << pid << " and QProcess " << process << "" << oendl; | 134 | odebug << "QProc: Constructor for pid " << pid << " and QProcess " << process << "" << oendl; |
135 | #endif | 135 | #endif |
136 | socketStdin = 0; | 136 | socketStdin = 0; |
137 | socketStdout = 0; | 137 | socketStdout = 0; |
138 | socketStderr = 0; | 138 | socketStderr = 0; |
139 | } | 139 | } |
140 | ~QProc() | 140 | ~QProc() |
141 | { | 141 | { |
142 | #if defined(QT_QPROCESS_DEBUG) | 142 | #if defined(QT_QPROCESS_DEBUG) |
143 | odebug << "QProc: Destructor for pid " << pid << " and QProcess " << process << "" << oendl; | 143 | odebug << "QProc: Destructor for pid " << pid << " and QProcess " << process << "" << oendl; |
144 | #endif | 144 | #endif |
145 | if ( process != 0 ) { | 145 | if ( process != 0 ) { |
146 | if ( process->d->notifierStdin ) | 146 | if ( process->d->notifierStdin ) |
147 | process->d->notifierStdin->setEnabled( FALSE ); | 147 | process->d->notifierStdin->setEnabled( FALSE ); |
148 | if ( process->d->notifierStdout ) | 148 | if ( process->d->notifierStdout ) |
149 | process->d->notifierStdout->setEnabled( FALSE ); | 149 | process->d->notifierStdout->setEnabled( FALSE ); |
150 | if ( process->d->notifierStderr ) | 150 | if ( process->d->notifierStderr ) |
151 | process->d->notifierStderr->setEnabled( FALSE ); | 151 | process->d->notifierStderr->setEnabled( FALSE ); |
152 | process->d->proc = 0; | 152 | process->d->proc = 0; |
153 | } | 153 | } |
154 | if( socketStdin != 0 ) | 154 | if( socketStdin != 0 ) |
155 | ::close( socketStdin ); | 155 | ::close( socketStdin ); |
156 | // ### close these sockets even on parent exit or is it better only on | 156 | // ### close these sockets even on parent exit or is it better only on |
157 | // sigchld (but what do I have to do with them on exit then)? | 157 | // sigchld (but what do I have to do with them on exit then)? |
158 | if( socketStdout != 0 ) | 158 | if( socketStdout != 0 ) |
159 | ::close( socketStdout ); | 159 | ::close( socketStdout ); |
160 | if( socketStderr != 0 ) | 160 | if( socketStderr != 0 ) |
161 | ::close( socketStderr ); | 161 | ::close( socketStderr ); |
162 | } | 162 | } |
163 | 163 | ||
164 | pid_t pid; | 164 | pid_t pid; |
165 | int socketStdin; | 165 | int socketStdin; |
166 | int socketStdout; | 166 | int socketStdout; |
167 | int socketStderr; | 167 | int socketStderr; |
168 | QProcess *process; | 168 | QProcess *process; |
169 | }; | 169 | }; |
170 | 170 | ||
171 | /*********************************************************************** | 171 | /*********************************************************************** |
172 | * | 172 | * |
173 | * QProcessManager | 173 | * QProcessManager |
174 | * | 174 | * |
175 | **********************************************************************/ | 175 | **********************************************************************/ |
176 | class QProcessManager : public QObject | 176 | class QProcessManager : public QObject |
177 | { | 177 | { |
178 | Q_OBJECT | 178 | Q_OBJECT |
179 | 179 | ||
180 | public: | 180 | public: |
181 | QProcessManager(); | 181 | QProcessManager(); |
182 | ~QProcessManager(); | 182 | ~QProcessManager(); |
183 | 183 | ||
184 | void append( QProc *p ); | 184 | void append( QProc *p ); |
185 | void remove( QProc *p ); | 185 | void remove( QProc *p ); |
186 | 186 | ||
187 | void cleanup(); | 187 | void cleanup(); |
188 | 188 | ||
189 | public slots: | 189 | public slots: |
190 | void removeMe(); | 190 | void removeMe(); |
191 | void sigchldHnd( int ); | 191 | void sigchldHnd( int ); |
192 | 192 | ||
193 | public: | 193 | public: |
194 | struct sigaction oldactChld; | 194 | struct sigaction oldactChld; |
195 | struct sigaction oldactPipe; | 195 | struct sigaction oldactPipe; |
196 | QList<QProc> *procList; | 196 | QList<QProc> *procList; |
197 | int sigchldFd[2]; | 197 | int sigchldFd[2]; |
198 | }; | 198 | }; |
199 | 199 | ||
200 | QCleanupHandler<QProcessManager> qprocess_cleanup_procmanager; | 200 | QCleanupHandler<QProcessManager> qprocess_cleanup_procmanager; |
201 | 201 | ||
202 | QProcessManager::QProcessManager() | 202 | QProcessManager::QProcessManager() |
203 | { | 203 | { |
204 | procList = new QList<QProc>; | 204 | procList = new QList<QProc>; |
205 | procList->setAutoDelete( TRUE ); | 205 | procList->setAutoDelete( TRUE ); |
206 | 206 | ||
207 | // The SIGCHLD handler writes to a socket to tell the manager that | 207 | // The SIGCHLD handler writes to a socket to tell the manager that |
208 | // something happened. This is done to get the processing in sync with the | 208 | // something happened. This is done to get the processing in sync with the |
209 | // event reporting. | 209 | // event reporting. |
210 | if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) { | 210 | if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) { |
211 | sigchldFd[0] = 0; | 211 | sigchldFd[0] = 0; |
212 | sigchldFd[1] = 0; | 212 | sigchldFd[1] = 0; |
213 | } else { | 213 | } else { |
214 | #if defined(QT_QPROCESS_DEBUG) | 214 | #if defined(QT_QPROCESS_DEBUG) |
215 | odebug << "QProcessManager: install socket notifier (" << sigchldFd[1] << ")" << oendl; | 215 | odebug << "QProcessManager: install socket notifier (" << sigchldFd[1] << ")" << oendl; |
216 | #endif | 216 | #endif |
217 | QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1], | 217 | QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1], |
218 | QSocketNotifier::Read, this ); | 218 | QSocketNotifier::Read, this ); |
219 | connect( sn, SIGNAL(activated(int)), | 219 | connect( sn, SIGNAL(activated(int)), |
220 | this, SLOT(sigchldHnd(int)) ); | 220 | this, SLOT(sigchldHnd(int)) ); |
221 | sn->setEnabled( TRUE ); | 221 | sn->setEnabled( TRUE ); |
222 | } | 222 | } |
223 | 223 | ||
224 | // install a SIGCHLD handler and ignore SIGPIPE | 224 | // install a SIGCHLD handler and ignore SIGPIPE |
225 | struct sigaction act; | 225 | struct sigaction act; |
226 | 226 | ||
227 | #if defined(QT_QPROCESS_DEBUG) | 227 | #if defined(QT_QPROCESS_DEBUG) |
228 | odebug << "QProcessManager: install a SIGCHLD handler" << oendl; | 228 | odebug << "QProcessManager: install a SIGCHLD handler" << oendl; |
229 | #endif | 229 | #endif |
230 | act.sa_handler = qt_C_sigchldHnd; | 230 | act.sa_handler = qt_C_sigchldHnd; |
231 | sigemptyset( &(act.sa_mask) ); | 231 | sigemptyset( &(act.sa_mask) ); |
232 | sigaddset( &(act.sa_mask), SIGCHLD ); | 232 | sigaddset( &(act.sa_mask), SIGCHLD ); |
233 | act.sa_flags = SA_NOCLDSTOP; | 233 | act.sa_flags = SA_NOCLDSTOP; |
234 | #if defined(SA_RESTART) | 234 | #if defined(SA_RESTART) |
235 | act.sa_flags |= SA_RESTART; | 235 | act.sa_flags |= SA_RESTART; |
236 | #endif | 236 | #endif |
237 | if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 ) | 237 | if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 ) |
238 | owarn << "Error installing SIGCHLD handler" << oendl; | 238 | owarn << "Error installing SIGCHLD handler" << oendl; |
239 | 239 | ||
240 | #if defined(QT_QPROCESS_DEBUG) | 240 | #if defined(QT_QPROCESS_DEBUG) |
241 | odebug << "QProcessManager: install a SIGPIPE handler (SIG_IGN)" << oendl; | 241 | odebug << "QProcessManager: install a SIGPIPE handler (SIG_IGN)" << oendl; |
242 | #endif | 242 | #endif |
243 | /* | 243 | /* |
244 | Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround | 244 | Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround |
245 | for a strange problem where GNU tar (called by backuprestore) | 245 | for a strange problem where GNU tar (called by backuprestore) |
246 | would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd | 246 | would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd |
247 | is never even called, yet this avoids the hang. | 247 | is never even called, yet this avoids the hang. |
248 | */ | 248 | */ |
249 | act.sa_handler = qt_C_sigpipeHnd; | 249 | act.sa_handler = qt_C_sigpipeHnd; |
250 | sigemptyset( &(act.sa_mask) ); | 250 | sigemptyset( &(act.sa_mask) ); |
251 | sigaddset( &(act.sa_mask), SIGPIPE ); | 251 | sigaddset( &(act.sa_mask), SIGPIPE ); |
252 | act.sa_flags = 0; | 252 | act.sa_flags = 0; |
253 | if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 ) | 253 | if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 ) |
254 | owarn << "Error installing SIGPIPE handler" << oendl; | 254 | owarn << "Error installing SIGPIPE handler" << oendl; |
255 | } | 255 | } |
256 | 256 | ||
257 | QProcessManager::~QProcessManager() | 257 | QProcessManager::~QProcessManager() |
258 | { | 258 | { |
259 | delete procList; | 259 | delete procList; |
260 | 260 | ||
261 | if ( sigchldFd[0] != 0 ) | 261 | if ( sigchldFd[0] != 0 ) |
262 | ::close( sigchldFd[0] ); | 262 | ::close( sigchldFd[0] ); |
263 | if ( sigchldFd[1] != 0 ) | 263 | if ( sigchldFd[1] != 0 ) |
264 | ::close( sigchldFd[1] ); | 264 | ::close( sigchldFd[1] ); |
265 | 265 | ||
266 | // restore SIGCHLD handler | 266 | // restore SIGCHLD handler |
267 | #if defined(QT_QPROCESS_DEBUG) | 267 | #if defined(QT_QPROCESS_DEBUG) |
268 | odebug << "QProcessManager: restore old sigchild handler" << oendl; | 268 | odebug << "QProcessManager: restore old sigchild handler" << oendl; |
269 | #endif | 269 | #endif |
270 | if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 ) | 270 | if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 ) |
271 | owarn << "Error restoring SIGCHLD handler" << oendl; | 271 | owarn << "Error restoring SIGCHLD handler" << oendl; |
272 | 272 | ||
273 | #if defined(QT_QPROCESS_DEBUG) | 273 | #if defined(QT_QPROCESS_DEBUG) |
274 | odebug << "QProcessManager: restore old sigpipe handler" << oendl; | 274 | odebug << "QProcessManager: restore old sigpipe handler" << oendl; |
275 | #endif | 275 | #endif |
276 | if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 ) | 276 | if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 ) |
277 | owarn << "Error restoring SIGPIPE handler" << oendl; | 277 | owarn << "Error restoring SIGPIPE handler" << oendl; |
278 | } | 278 | } |
279 | 279 | ||
280 | void QProcessManager::append( QProc *p ) | 280 | void QProcessManager::append( QProc *p ) |
281 | { | 281 | { |
282 | procList->append( p ); | 282 | procList->append( p ); |
283 | #if defined(QT_QPROCESS_DEBUG) | 283 | #if defined(QT_QPROCESS_DEBUG) |
284 | odebug << "QProcessManager: append process (procList.count(): " << procList->count() << ")" << oendl; | 284 | odebug << "QProcessManager: append process (procList.count(): " << procList->count() << ")" << oendl; |
285 | #endif | 285 | #endif |
286 | } | 286 | } |
287 | 287 | ||
288 | void QProcessManager::remove( QProc *p ) | 288 | void QProcessManager::remove( QProc *p ) |
289 | { | 289 | { |
290 | procList->remove( p ); | 290 | procList->remove( p ); |
291 | #if defined(QT_QPROCESS_DEBUG) | 291 | #if defined(QT_QPROCESS_DEBUG) |
292 | odebug << "QProcessManager: remove process (procList.count(): " << procList->count() << ")" << oendl; | 292 | odebug << "QProcessManager: remove process (procList.count(): " << procList->count() << ")" << oendl; |
293 | #endif | 293 | #endif |
294 | cleanup(); | 294 | cleanup(); |
295 | } | 295 | } |
296 | 296 | ||
297 | void QProcessManager::cleanup() | 297 | void QProcessManager::cleanup() |
298 | { | 298 | { |
299 | if ( procList->count() == 0 ) { | 299 | if ( procList->count() == 0 ) { |
300 | QTimer::singleShot( 0, this, SLOT(removeMe()) ); | 300 | QTimer::singleShot( 0, this, SLOT(removeMe()) ); |
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
304 | void QProcessManager::removeMe() | 304 | void QProcessManager::removeMe() |
305 | { | 305 | { |
306 | if ( procList->count() == 0 ) { | 306 | if ( procList->count() == 0 ) { |
307 | qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager ); | 307 | qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager ); |
308 | QProcessPrivate::procManager = 0; | 308 | QProcessPrivate::procManager = 0; |
309 | delete this; | 309 | delete this; |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | void QProcessManager::sigchldHnd( int fd ) | 313 | void QProcessManager::sigchldHnd( int fd ) |
314 | { | 314 | { |
315 | char tmp; | 315 | char tmp; |
316 | ::read( fd, &tmp, sizeof(tmp) ); | 316 | ::read( fd, &tmp, sizeof(tmp) ); |
317 | #if defined(QT_QPROCESS_DEBUG) | 317 | #if defined(QT_QPROCESS_DEBUG) |
318 | odebug << "QProcessManager::sigchldHnd()" << oendl; | 318 | odebug << "QProcessManager::sigchldHnd()" << oendl; |
319 | #endif | 319 | #endif |
320 | QProc *proc; | 320 | QProc *proc; |
321 | QProcess *process; | 321 | QProcess *process; |
322 | bool removeProc; | 322 | bool removeProc; |
323 | proc = procList->first(); | 323 | proc = procList->first(); |
324 | while ( proc != 0 ) { | 324 | while ( proc != 0 ) { |
325 | removeProc = FALSE; | 325 | removeProc = FALSE; |
326 | process = proc->process; | 326 | process = proc->process; |
327 | QProcess *process_exit_notify=0; | 327 | QProcess *process_exit_notify=0; |
328 | if ( process != 0 ) { | 328 | if ( process != 0 ) { |
329 | if ( !process->isRunning() ) { | 329 | if ( !process->isRunning() ) { |
330 | #if defined(QT_QPROCESS_DEBUG) | 330 | #if defined(QT_QPROCESS_DEBUG) |
331 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess available)" << oendl; | 331 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess available)" << oendl; |
332 | #endif | 332 | #endif |
333 | // read pending data | 333 | // read pending data |
334 | int nbytes = 0; | 334 | int nbytes = 0; |
335 | if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { | 335 | if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { |
336 | #if defined(QT_QPROCESS_DEBUG) | 336 | #if defined(QT_QPROCESS_DEBUG) |
337 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stdout" << oendl; | 337 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stdout" << oendl; |
338 | #endif | 338 | #endif |
339 | process->socketRead( proc->socketStdout ); | 339 | process->socketRead( proc->socketStdout ); |
340 | } | 340 | } |
341 | nbytes = 0; | 341 | nbytes = 0; |
342 | if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { | 342 | if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { |
343 | #if defined(QT_QPROCESS_DEBUG) | 343 | #if defined(QT_QPROCESS_DEBUG) |
344 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stderr" << oendl; | 344 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stderr" << oendl; |
345 | #endif | 345 | #endif |
346 | process->socketRead( proc->socketStderr ); | 346 | process->socketRead( proc->socketStderr ); |
347 | } | 347 | } |
348 | 348 | ||
349 | if ( process->notifyOnExit ) | 349 | if ( process->notifyOnExit ) |
350 | process_exit_notify = process; | 350 | process_exit_notify = process; |
351 | 351 | ||
352 | removeProc = TRUE; | 352 | removeProc = TRUE; |
353 | } | 353 | } |
354 | } else { | 354 | } else { |
355 | int status; | 355 | int status; |
356 | if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { | 356 | if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { |
357 | #if defined(QT_QPROCESS_DEBUG) | 357 | #if defined(QT_QPROCESS_DEBUG) |
358 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess not available)" << oendl; | 358 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess not available)" << oendl; |
359 | #endif | 359 | #endif |
360 | removeProc = TRUE; | 360 | removeProc = TRUE; |
361 | } | 361 | } |
362 | } | 362 | } |
363 | if ( removeProc ) { | 363 | if ( removeProc ) { |
364 | QProc *oldproc = proc; | 364 | QProc *oldproc = proc; |
365 | proc = procList->next(); | 365 | proc = procList->next(); |
366 | remove( oldproc ); | 366 | remove( oldproc ); |
367 | } else { | 367 | } else { |
368 | proc = procList->next(); | 368 | proc = procList->next(); |
369 | } | 369 | } |
370 | if ( process_exit_notify ) | 370 | if ( process_exit_notify ) |
371 | emit process_exit_notify->processExited(); | 371 | emit process_exit_notify->processExited(); |
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
375 | #include "qprocess_unix.moc" | 375 | #include "qprocess_unix.moc" |
376 | 376 | ||
377 | 377 | ||
378 | /*********************************************************************** | 378 | /*********************************************************************** |
379 | * | 379 | * |
380 | * QProcessPrivate | 380 | * QProcessPrivate |
381 | * | 381 | * |
382 | **********************************************************************/ | 382 | **********************************************************************/ |
383 | QProcessManager *QProcessPrivate::procManager = 0; | 383 | QProcessManager *QProcessPrivate::procManager = 0; |
384 | 384 | ||
385 | QProcessPrivate::QProcessPrivate() | 385 | QProcessPrivate::QProcessPrivate() |
386 | { | 386 | { |
387 | #if defined(QT_QPROCESS_DEBUG) | 387 | #if defined(QT_QPROCESS_DEBUG) |
388 | odebug << "QProcessPrivate: Constructor" << oendl; | 388 | odebug << "QProcessPrivate: Constructor" << oendl; |
389 | #endif | 389 | #endif |
390 | stdinBufRead = 0; | 390 | stdinBufRead = 0; |
391 | 391 | ||
392 | notifierStdin = 0; | 392 | notifierStdin = 0; |
393 | notifierStdout = 0; | 393 | notifierStdout = 0; |
394 | notifierStderr = 0; | 394 | notifierStderr = 0; |
395 | 395 | ||
396 | exitValuesCalculated = FALSE; | 396 | exitValuesCalculated = FALSE; |
397 | socketReadCalled = FALSE; | 397 | socketReadCalled = FALSE; |
398 | 398 | ||
399 | proc = 0; | 399 | proc = 0; |
400 | } | 400 | } |
401 | 401 | ||
402 | QProcessPrivate::~QProcessPrivate() | 402 | QProcessPrivate::~QProcessPrivate() |
403 | { | 403 | { |
404 | #if defined(QT_QPROCESS_DEBUG) | 404 | #if defined(QT_QPROCESS_DEBUG) |
405 | odebug << "QProcessPrivate: Destructor" << oendl; | 405 | odebug << "QProcessPrivate: Destructor" << oendl; |
406 | #endif | 406 | #endif |
407 | 407 | ||
408 | if ( proc != 0 ) { | 408 | if ( proc != 0 ) { |
409 | if ( proc->socketStdin != 0 ) { | 409 | if ( proc->socketStdin != 0 ) { |
410 | ::close( proc->socketStdin ); | 410 | ::close( proc->socketStdin ); |
411 | proc->socketStdin = 0; | 411 | proc->socketStdin = 0; |
412 | } | 412 | } |
413 | proc->process = 0; | 413 | proc->process = 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | while ( !stdinBuf.isEmpty() ) { | 416 | while ( !stdinBuf.isEmpty() ) { |
417 | delete stdinBuf.dequeue(); | 417 | delete stdinBuf.dequeue(); |
418 | } | 418 | } |
419 | delete notifierStdin; | 419 | delete notifierStdin; |
420 | delete notifierStdout; | 420 | delete notifierStdout; |
421 | delete notifierStderr; | 421 | delete notifierStderr; |
422 | } | 422 | } |
423 | 423 | ||
424 | /* | 424 | /* |
425 | Closes all open sockets in the child process that are not needed by the child | 425 | Closes all open sockets in the child process that are not needed by the child |
426 | process. Otherwise one child may have an open socket on standard input, etc. | 426 | process. Otherwise one child may have an open socket on standard input, etc. |
427 | of another child. | 427 | of another child. |
428 | */ | 428 | */ |
429 | void QProcessPrivate::closeOpenSocketsForChild() | 429 | void QProcessPrivate::closeOpenSocketsForChild() |
430 | { | 430 | { |
431 | if ( procManager != 0 ) { | 431 | if ( procManager != 0 ) { |
432 | if ( procManager->sigchldFd[0] != 0 ) | 432 | if ( procManager->sigchldFd[0] != 0 ) |
433 | ::close( procManager->sigchldFd[0] ); | 433 | ::close( procManager->sigchldFd[0] ); |
434 | if ( procManager->sigchldFd[1] != 0 ) | 434 | if ( procManager->sigchldFd[1] != 0 ) |
435 | ::close( procManager->sigchldFd[1] ); | 435 | ::close( procManager->sigchldFd[1] ); |
436 | 436 | ||
437 | // close also the sockets from other QProcess instances | 437 | // close also the sockets from other QProcess instances |
438 | QProc *proc; | 438 | QProc *proc; |
439 | for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) { | 439 | for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) { |
440 | ::close( proc->socketStdin ); | 440 | ::close( proc->socketStdin ); |
441 | ::close( proc->socketStdout ); | 441 | ::close( proc->socketStdout ); |
442 | ::close( proc->socketStderr ); | 442 | ::close( proc->socketStderr ); |
443 | } | 443 | } |
444 | } | 444 | } |
445 | } | 445 | } |
446 | 446 | ||
447 | void QProcessPrivate::newProc( pid_t pid, QProcess *process ) | 447 | void QProcessPrivate::newProc( pid_t pid, QProcess *process ) |
448 | { | 448 | { |
449 | proc = new QProc( pid, process ); | 449 | proc = new QProc( pid, process ); |
450 | if ( procManager == 0 ) { | 450 | if ( procManager == 0 ) { |
451 | procManager = new QProcessManager; | 451 | procManager = new QProcessManager; |
452 | qprocess_cleanup_procmanager.add( &procManager ); | 452 | qprocess_cleanup_procmanager.add( &procManager ); |
453 | } | 453 | } |
454 | // the QProcessManager takes care of deleting the QProc instances | 454 | // the QProcessManager takes care of deleting the QProc instances |
455 | procManager->append( proc ); | 455 | procManager->append( proc ); |
456 | } | 456 | } |
457 | 457 | ||
458 | /*********************************************************************** | 458 | /*********************************************************************** |
459 | * | 459 | * |
460 | * sigchld handler callback | 460 | * sigchld handler callback |
461 | * | 461 | * |
462 | **********************************************************************/ | 462 | **********************************************************************/ |
463 | QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS ) | 463 | QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS ) |
464 | { | 464 | { |
465 | if ( QProcessPrivate::procManager == 0 ) | 465 | if ( QProcessPrivate::procManager == 0 ) |
466 | return; | 466 | return; |
467 | if ( QProcessPrivate::procManager->sigchldFd[0] == 0 ) | 467 | if ( QProcessPrivate::procManager->sigchldFd[0] == 0 ) |
468 | return; | 468 | return; |
469 | 469 | ||
470 | char a = 1; | 470 | char a = 1; |
471 | ::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ); | 471 | ::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ); |
472 | } | 472 | } |
473 | QT_SIGNAL_RETTYPE qt_C_sigpipeHnd( QT_SIGNAL_ARGS ) | 473 | QT_SIGNAL_RETTYPE qt_C_sigpipeHnd( QT_SIGNAL_ARGS ) |
474 | { | 474 | { |
475 | // Ignore (but in a way somehow different to SIG_IGN). | 475 | // Ignore (but in a way somehow different to SIG_IGN). |
476 | } | 476 | } |
477 | 477 | ||
478 | 478 | ||
479 | /*********************************************************************** | 479 | /*********************************************************************** |
480 | * | 480 | * |
481 | * QProcess | 481 | * QProcess |
482 | * | 482 | * |
483 | **********************************************************************/ | 483 | **********************************************************************/ |
484 | /*! | 484 | /*! |
485 | This private class does basic initialization. | 485 | This private class does basic initialization. |
486 | */ | 486 | */ |
487 | void QProcess::init() | 487 | void QProcess::init() |
488 | { | 488 | { |
489 | d = new QProcessPrivate(); | 489 | d = new QProcessPrivate(); |
490 | exitStat = 0; | 490 | exitStat = 0; |
491 | exitNormal = FALSE; | 491 | exitNormal = FALSE; |
492 | } | 492 | } |
493 | 493 | ||
494 | /*! | 494 | /*! |
495 | This private class resets the process variables, etc. so that it can be used | 495 | This private class resets the process variables, etc. so that it can be used |
496 | for another process to start. | 496 | for another process to start. |
497 | */ | 497 | */ |
498 | void QProcess::reset() | 498 | void QProcess::reset() |
499 | { | 499 | { |
500 | delete d; | 500 | delete d; |
501 | d = new QProcessPrivate(); | 501 | d = new QProcessPrivate(); |
502 | exitStat = 0; | 502 | exitStat = 0; |
503 | exitNormal = FALSE; | 503 | exitNormal = FALSE; |
504 | d->bufStdout.resize( 0 ); | 504 | d->bufStdout.resize( 0 ); |
505 | d->bufStderr.resize( 0 ); | 505 | d->bufStderr.resize( 0 ); |
506 | } | 506 | } |
507 | 507 | ||
508 | QByteArray* QProcess::bufStdout() | 508 | QByteArray* QProcess::bufStdout() |
509 | { | 509 | { |
510 | if ( d->proc && d->proc->socketStdout ) { | 510 | if ( d->proc && d->proc->socketStdout ) { |
511 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see | 511 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see |
512 | // if data is available)? | 512 | // if data is available)? |
513 | socketRead( d->proc->socketStdout ); | 513 | socketRead( d->proc->socketStdout ); |
514 | } | 514 | } |
515 | return &d->bufStdout; | 515 | return &d->bufStdout; |
516 | } | 516 | } |
517 | 517 | ||
518 | QByteArray* QProcess::bufStderr() | 518 | QByteArray* QProcess::bufStderr() |
519 | { | 519 | { |
520 | if ( d->proc && d->proc->socketStderr ) { | 520 | if ( d->proc && d->proc->socketStderr ) { |
521 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see | 521 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see |
522 | // if data is available)? | 522 | // if data is available)? |
523 | socketRead( d->proc->socketStderr ); | 523 | socketRead( d->proc->socketStderr ); |
524 | } | 524 | } |
525 | return &d->bufStderr; | 525 | return &d->bufStderr; |
526 | } | 526 | } |
527 | 527 | ||
528 | void QProcess::consumeBufStdout( int consume ) | 528 | void QProcess::consumeBufStdout( int consume ) |
529 | { | 529 | { |
530 | uint n = d->bufStdout.size(); | 530 | uint n = d->bufStdout.size(); |
531 | if ( consume==-1 || (uint)consume >= n ) { | 531 | if ( consume==-1 || (uint)consume >= n ) { |
532 | d->bufStdout.resize( 0 ); | 532 | d->bufStdout.resize( 0 ); |
533 | } else { | 533 | } else { |
534 | QByteArray tmp( n - consume ); | 534 | QByteArray tmp( n - consume ); |
535 | memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume ); | 535 | memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume ); |
536 | d->bufStdout = tmp; | 536 | d->bufStdout = tmp; |
537 | } | 537 | } |
538 | } | 538 | } |
539 | 539 | ||
540 | void QProcess::consumeBufStderr( int consume ) | 540 | void QProcess::consumeBufStderr( int consume ) |
541 | { | 541 | { |
542 | uint n = d->bufStderr.size(); | 542 | uint n = d->bufStderr.size(); |
543 | if ( consume==-1 || (uint)consume >= n ) { | 543 | if ( consume==-1 || (uint)consume >= n ) { |
544 | d->bufStderr.resize( 0 ); | 544 | d->bufStderr.resize( 0 ); |
545 | } else { | 545 | } else { |
546 | QByteArray tmp( n - consume ); | 546 | QByteArray tmp( n - consume ); |
547 | memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume ); | 547 | memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume ); |
548 | d->bufStderr = tmp; | 548 | d->bufStderr = tmp; |
549 | } | 549 | } |
550 | } | 550 | } |
551 | 551 | ||
552 | /*! | 552 | /*! |
553 | Destroys the class. | 553 | Destroys the class. |
554 | 554 | ||
555 | If the process is running, it is NOT terminated! Standard input, standard | 555 | If the process is running, it is NOT terminated! Standard input, standard |
556 | output and standard error of the process are closed. | 556 | output and standard error of the process are closed. |
557 | 557 | ||
558 | You can connect the destroyed() signal to the kill() slot, if you want the | 558 | You can connect the destroyed() signal to the kill() slot, if you want the |
559 | process to be terminated automatically when the class is destroyed. | 559 | process to be terminated automatically when the class is destroyed. |
560 | 560 | ||
561 | \sa tryTerminate() kill() | 561 | \sa tryTerminate() kill() |
562 | */ | 562 | */ |
563 | QProcess::~QProcess() | 563 | QProcess::~QProcess() |
564 | { | 564 | { |
565 | delete d; | 565 | delete d; |
566 | } | 566 | } |
567 | 567 | ||
568 | /*! | 568 | /*! |
569 | Tries to run a process for the command and arguments that were specified with | 569 | Tries to run a process for the command and arguments that were specified with |
570 | setArguments(), addArgument() or that were specified in the constructor. The | 570 | setArguments(), addArgument() or that were specified in the constructor. The |
571 | command is searched in the path for executable programs; you can also use an | 571 | command is searched in the path for executable programs; you can also use an |
572 | absolute path to the command. | 572 | absolute path to the command. |
573 | 573 | ||
574 | If \a env is null, then the process is started with the same environment as | 574 | If \a env is null, then the process is started with the same environment as |
575 | the starting process. If \a env is non-null, then the values in the | 575 | the starting process. If \a env is non-null, then the values in the |
576 | stringlist are interpreted as environment setttings of the form \c | 576 | stringlist are interpreted as environment setttings of the form \c |
577 | {key=value} and the process is started in these environment settings. For | 577 | {key=value} and the process is started in these environment settings. For |
578 | convenience, there is a small exception to this rule: under Unix, if \a env | 578 | convenience, there is a small exception to this rule: under Unix, if \a env |
579 | does not contain any settings for the environment variable \c | 579 | does not contain any settings for the environment variable \c |
580 | LD_LIBRARY_PATH, then this variable is inherited from the starting process; | 580 | LD_LIBRARY_PATH, then this variable is inherited from the starting process; |
581 | under Windows the same applies for the enverionment varialbe \c PATH. | 581 | under Windows the same applies for the enverionment varialbe \c PATH. |
582 | 582 | ||
583 | Returns TRUE if the process could be started, otherwise FALSE. | 583 | Returns TRUE if the process could be started, otherwise FALSE. |
584 | 584 | ||
585 | You can write data to standard input of the process with | 585 | You can write data to standard input of the process with |
586 | writeToStdin(), you can close standard input with closeStdin() and you can | 586 | writeToStdin(), you can close standard input with closeStdin() and you can |
587 | terminate the process tryTerminate() resp. kill(). | 587 | terminate the process tryTerminate() resp. kill(). |
588 | 588 | ||
589 | You can call this function even when there already is a running | 589 | You can call this function even when there already is a running |
590 | process in this object. In this case, QProcess closes standard input | 590 | process in this object. In this case, QProcess closes standard input |
591 | of the old process and deletes pending data, i.e., you loose all | 591 | of the old process and deletes pending data, i.e., you loose all |
592 | control over that process, but the process is not terminated. This applies | 592 | control over that process, but the process is not terminated. This applies |
593 | also if the process could not be started. (On operating systems that have | 593 | also if the process could not be started. (On operating systems that have |
594 | zombie processes, Qt will also wait() on the old process.) | 594 | zombie processes, Qt will also wait() on the old process.) |
595 | 595 | ||
596 | \sa launch() closeStdin() | 596 | \sa launch() closeStdin() |
597 | */ | 597 | */ |
598 | bool QProcess::start( QStringList *env ) | 598 | bool QProcess::start( QStringList *env ) |
599 | { | 599 | { |
600 | #if defined(QT_QPROCESS_DEBUG) | 600 | #if defined(QT_QPROCESS_DEBUG) |
601 | odebug << "QProcess::start()" << oendl; | 601 | odebug << "QProcess::start()" << oendl; |
602 | #endif | 602 | #endif |
603 | reset(); | 603 | reset(); |
604 | 604 | ||
605 | int sStdin[2]; | 605 | int sStdin[2]; |
606 | int sStdout[2]; | 606 | int sStdout[2]; |
607 | int sStderr[2]; | 607 | int sStderr[2]; |
608 | 608 | ||
609 | // open sockets for piping | 609 | // open sockets for piping |
610 | if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) { | 610 | if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) { |
611 | return FALSE; | 611 | return FALSE; |
612 | } | 612 | } |
613 | if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) { | 613 | if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) { |
614 | return FALSE; | 614 | return FALSE; |
615 | } | 615 | } |
616 | if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) { | 616 | if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) { |
617 | return FALSE; | 617 | return FALSE; |
618 | } | 618 | } |
619 | 619 | ||
620 | // the following pipe is only used to determine if the process could be | 620 | // the following pipe is only used to determine if the process could be |
621 | // started | 621 | // started |
622 | int fd[2]; | 622 | int fd[2]; |
623 | if ( pipe( fd ) < 0 ) { | 623 | if ( pipe( fd ) < 0 ) { |
624 | // non critical error, go on | 624 | // non critical error, go on |
625 | fd[0] = 0; | 625 | fd[0] = 0; |
626 | fd[1] = 0; | 626 | fd[1] = 0; |
627 | } | 627 | } |
628 | 628 | ||
629 | // construct the arguments for exec | 629 | // construct the arguments for exec |
630 | QCString *arglistQ = new QCString[ _arguments.count() + 1 ]; | 630 | QCString *arglistQ = new QCString[ _arguments.count() + 1 ]; |
631 | const char** arglist = new const char*[ _arguments.count() + 1 ]; | 631 | const char** arglist = new const char*[ _arguments.count() + 1 ]; |
632 | int i = 0; | 632 | int i = 0; |
633 | for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) { | 633 | for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) { |
634 | arglistQ[i] = (*it).local8Bit(); | 634 | arglistQ[i] = (*it).local8Bit(); |
635 | arglist[i] = arglistQ[i]; | 635 | arglist[i] = arglistQ[i]; |
636 | #if defined(QT_QPROCESS_DEBUG) | 636 | #if defined(QT_QPROCESS_DEBUG) |
637 | odebug << "QProcess::start(): arg " << i << " = " << arglist[i] << "" << oendl; | 637 | odebug << "QProcess::start(): arg " << i << " = " << arglist[i] << "" << oendl; |
638 | #endif | 638 | #endif |
639 | i++; | 639 | i++; |
640 | } | 640 | } |
641 | arglist[i] = 0; | 641 | arglist[i] = 0; |
642 | 642 | ||
643 | // Must make sure signal handlers are installed before exec'ing | 643 | // Must make sure signal handlers are installed before exec'ing |
644 | // in case the process exits quickly. | 644 | // in case the process exits quickly. |
645 | if ( d->procManager == 0 ) { | 645 | if ( d->procManager == 0 ) { |
646 | d->procManager = new QProcessManager; | 646 | d->procManager = new QProcessManager; |
647 | qprocess_cleanup_procmanager.add( &d->procManager ); | 647 | qprocess_cleanup_procmanager.add( &d->procManager ); |
648 | } | 648 | } |
649 | 649 | ||
650 | // fork and exec | 650 | // fork and exec |
651 | QApplication::flushX(); | 651 | QApplication::flushX(); |
652 | pid_t pid = fork(); | 652 | pid_t pid = fork(); |
653 | if ( pid == 0 ) { | 653 | if ( pid == 0 ) { |
654 | // child | 654 | // child |
655 | d->closeOpenSocketsForChild(); | 655 | d->closeOpenSocketsForChild(); |
656 | if ( comms & Stdin ) { | 656 | if ( comms & Stdin ) { |
657 | ::close( sStdin[1] ); | 657 | ::close( sStdin[1] ); |
658 | ::dup2( sStdin[0], STDIN_FILENO ); | 658 | ::dup2( sStdin[0], STDIN_FILENO ); |
659 | } | 659 | } |
660 | if ( comms & Stdout ) { | 660 | if ( comms & Stdout ) { |
661 | ::close( sStdout[0] ); | 661 | ::close( sStdout[0] ); |
662 | ::dup2( sStdout[1], STDOUT_FILENO ); | 662 | ::dup2( sStdout[1], STDOUT_FILENO ); |
663 | } | 663 | } |
664 | if ( comms & Stderr ) { | 664 | if ( comms & Stderr ) { |
665 | ::close( sStderr[0] ); | 665 | ::close( sStderr[0] ); |
666 | ::dup2( sStderr[1], STDERR_FILENO ); | 666 | ::dup2( sStderr[1], STDERR_FILENO ); |
667 | } | 667 | } |
668 | if ( comms & DupStderr ) { | 668 | if ( comms & DupStderr ) { |
669 | ::dup2( STDOUT_FILENO, STDERR_FILENO ); | 669 | ::dup2( STDOUT_FILENO, STDERR_FILENO ); |
670 | } | 670 | } |
671 | #ifndef QT_NO_DIR | 671 | #ifndef QT_NO_DIR |
672 | ::chdir( workingDir.absPath().latin1() ); | 672 | ::chdir( workingDir.absPath().latin1() ); |
673 | #endif | 673 | #endif |
674 | if ( fd[0] ) | 674 | if ( fd[0] ) |
675 | ::close( fd[0] ); | 675 | ::close( fd[0] ); |
676 | if ( fd[1] ) | 676 | if ( fd[1] ) |
677 | ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess | 677 | ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess |
678 | 678 | ||
679 | if ( env == 0 ) { // inherit environment and start process | 679 | if ( env == 0 ) { // inherit environment and start process |
680 | ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice | 680 | ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice |
681 | } else { // start process with environment settins as specified in env | 681 | } else { // start process with environment settins as specified in env |
682 | // construct the environment for exec | 682 | // construct the environment for exec |
683 | int numEntries = env->count(); | 683 | int numEntries = env->count(); |
684 | bool setLibraryPath = | 684 | bool setLibraryPath = |
685 | env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() && | 685 | env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() && |
686 | getenv( "LD_LIBRARY_PATH" ) != 0; | 686 | getenv( "LD_LIBRARY_PATH" ) != 0; |
687 | if ( setLibraryPath ) | 687 | if ( setLibraryPath ) |
688 | numEntries++; | 688 | numEntries++; |
689 | QCString *envlistQ = new QCString[ numEntries + 1 ]; | 689 | QCString *envlistQ = new QCString[ numEntries + 1 ]; |
690 | const char** envlist = new const char*[ numEntries + 1 ]; | 690 | const char** envlist = new const char*[ numEntries + 1 ]; |
691 | int i = 0; | 691 | int i = 0; |
692 | if ( setLibraryPath ) { | 692 | if ( setLibraryPath ) { |
693 | envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit(); | 693 | envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit(); |
694 | envlist[i] = envlistQ[i]; | 694 | envlist[i] = envlistQ[i]; |
695 | i++; | 695 | i++; |
696 | } | 696 | } |
697 | for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { | 697 | for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { |
698 | envlistQ[i] = (*it).local8Bit(); | 698 | envlistQ[i] = (*it).local8Bit(); |
699 | envlist[i] = envlistQ[i]; | 699 | envlist[i] = envlistQ[i]; |
700 | i++; | 700 | i++; |
701 | } | 701 | } |
702 | envlist[i] = 0; | 702 | envlist[i] = 0; |
703 | 703 | ||
704 | // look for the executable in the search path | 704 | // look for the executable in the search path |
705 | if ( _arguments.count()>0 && getenv("PATH")!=0 ) { | 705 | if ( _arguments.count()>0 && getenv("PATH")!=0 ) { |
706 | QString command = _arguments[0]; | 706 | QString command = _arguments[0]; |
707 | if ( !command.contains( '/' ) ) { | 707 | if ( !command.contains( '/' ) ) { |
708 | QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); | 708 | QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); |
709 | for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { | 709 | for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { |
710 | QString dir = *it; | 710 | QString dir = *it; |
711 | #ifdef Q_OS_MACX | 711 | #ifdef Q_OS_MACX |
712 | if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle | 712 | if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle |
713 | dir += "/" + command + ".app/Contents/MacOS"; | 713 | dir += "/" + command + ".app/Contents/MacOS"; |
714 | #endif | 714 | #endif |
715 | #ifndef QT_NO_DIR | 715 | #ifndef QT_NO_DIR |
716 | QFileInfo fileInfo( dir, command ); | 716 | QFileInfo fileInfo( dir, command ); |
717 | #else | 717 | #else |
718 | QFileInfo fileInfo( dir + "/" + command ); | 718 | QFileInfo fileInfo( dir + "/" + command ); |
719 | #endif | 719 | #endif |
720 | if ( fileInfo.isExecutable() ) { | 720 | if ( fileInfo.isExecutable() ) { |
721 | arglistQ[0] = fileInfo.filePath().local8Bit(); | 721 | arglistQ[0] = fileInfo.filePath().local8Bit(); |
722 | arglist[0] = arglistQ[0]; | 722 | arglist[0] = arglistQ[0]; |
723 | break; | 723 | break; |
724 | } | 724 | } |
725 | } | 725 | } |
726 | } | 726 | } |
727 | } | 727 | } |
728 | ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice | 728 | ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice |
729 | } | 729 | } |
730 | if ( fd[1] ) { | 730 | if ( fd[1] ) { |
731 | char buf = 0; | 731 | char buf = 0; |
732 | ::write( fd[1], &buf, 1 ); | 732 | ::write( fd[1], &buf, 1 ); |
733 | ::close( fd[1] ); | 733 | ::close( fd[1] ); |
734 | } | 734 | } |
735 | ::exit( -1 ); | 735 | ::exit( -1 ); |
736 | } else if ( pid == -1 ) { | 736 | } else if ( pid == -1 ) { |
737 | // error forking | 737 | // error forking |
738 | goto error; | 738 | goto error; |
739 | } | 739 | } |
740 | 740 | ||
741 | // test if exec was successful | 741 | // test if exec was successful |
742 | if ( fd[1] ) | 742 | if ( fd[1] ) |
743 | ::close( fd[1] ); | 743 | ::close( fd[1] ); |
744 | if ( fd[0] ) { | 744 | if ( fd[0] ) { |
745 | char buf; | 745 | char buf; |
746 | for ( ;; ) { | 746 | for ( ;; ) { |
747 | int n = ::read( fd[0], &buf, 1 ); | 747 | int n = ::read( fd[0], &buf, 1 ); |
748 | if ( n==1 ) { | 748 | if ( n==1 ) { |
749 | // socket was not closed => error | 749 | // socket was not closed => error |
750 | d->proc = 0; | 750 | d->proc = 0; |
751 | goto error; | 751 | goto error; |
752 | } else if ( n==-1 ) { | 752 | } else if ( n==-1 ) { |
753 | if ( errno==EAGAIN || errno==EINTR ) | 753 | if ( errno==EAGAIN || errno==EINTR ) |
754 | // try it again | 754 | // try it again |
755 | continue; | 755 | continue; |
756 | } | 756 | } |
757 | break; | 757 | break; |
758 | } | 758 | } |
759 | ::close( fd[0] ); | 759 | ::close( fd[0] ); |
760 | } | 760 | } |
761 | 761 | ||
762 | d->newProc( pid, this ); | 762 | d->newProc( pid, this ); |
763 | 763 | ||
764 | if ( comms & Stdin ) { | 764 | if ( comms & Stdin ) { |
765 | ::close( sStdin[0] ); | 765 | ::close( sStdin[0] ); |
766 | d->proc->socketStdin = sStdin[1]; | 766 | d->proc->socketStdin = sStdin[1]; |
767 | d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); | 767 | d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); |
768 | connect( d->notifierStdin, SIGNAL(activated(int)), | 768 | connect( d->notifierStdin, SIGNAL(activated(int)), |
769 | this, SLOT(socketWrite(int)) ); | 769 | this, SLOT(socketWrite(int)) ); |
770 | // setup notifiers for the sockets | 770 | // setup notifiers for the sockets |
771 | if ( !d->stdinBuf.isEmpty() ) { | 771 | if ( !d->stdinBuf.isEmpty() ) { |
772 | d->notifierStdin->setEnabled( TRUE ); | 772 | d->notifierStdin->setEnabled( TRUE ); |
773 | } | 773 | } |
774 | } | 774 | } |
775 | if ( comms & Stdout ) { | 775 | if ( comms & Stdout ) { |
776 | ::close( sStdout[1] ); | 776 | ::close( sStdout[1] ); |
777 | d->proc->socketStdout = sStdout[0]; | 777 | d->proc->socketStdout = sStdout[0]; |
778 | d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); | 778 | d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); |
779 | connect( d->notifierStdout, SIGNAL(activated(int)), | 779 | connect( d->notifierStdout, SIGNAL(activated(int)), |
780 | this, SLOT(socketRead(int)) ); | 780 | this, SLOT(socketRead(int)) ); |
781 | if ( ioRedirection ) | 781 | if ( ioRedirection ) |
782 | d->notifierStdout->setEnabled( TRUE ); | 782 | d->notifierStdout->setEnabled( TRUE ); |
783 | } | 783 | } |
784 | if ( comms & Stderr ) { | 784 | if ( comms & Stderr ) { |
785 | ::close( sStderr[1] ); | 785 | ::close( sStderr[1] ); |
786 | d->proc->socketStderr = sStderr[0]; | 786 | d->proc->socketStderr = sStderr[0]; |
787 | d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); | 787 | d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); |
788 | connect( d->notifierStderr, SIGNAL(activated(int)), | 788 | connect( d->notifierStderr, SIGNAL(activated(int)), |
789 | this, SLOT(socketRead(int)) ); | 789 | this, SLOT(socketRead(int)) ); |
790 | if ( ioRedirection ) | 790 | if ( ioRedirection ) |
791 | d->notifierStderr->setEnabled( TRUE ); | 791 | d->notifierStderr->setEnabled( TRUE ); |
792 | } | 792 | } |
793 | 793 | ||
794 | // cleanup and return | 794 | // cleanup and return |
795 | delete[] arglistQ; | 795 | delete[] arglistQ; |
796 | delete[] arglist; | 796 | delete[] arglist; |
797 | return TRUE; | 797 | return TRUE; |
798 | 798 | ||
799 | error: | 799 | error: |
800 | #if defined(QT_QPROCESS_DEBUG) | 800 | #if defined(QT_QPROCESS_DEBUG) |
801 | odebug << "QProcess::start(): error starting process" << oendl; | 801 | odebug << "QProcess::start(): error starting process" << oendl; |
802 | #endif | 802 | #endif |
803 | if ( d->procManager ) | 803 | if ( d->procManager ) |
804 | d->procManager->cleanup(); | 804 | d->procManager->cleanup(); |
805 | if ( comms & Stdin ) { | 805 | if ( comms & Stdin ) { |
806 | ::close( sStdin[1] ); | 806 | ::close( sStdin[1] ); |
807 | ::close( sStdin[0] ); | 807 | ::close( sStdin[0] ); |
808 | } | 808 | } |
809 | if ( comms & Stdout ) { | 809 | if ( comms & Stdout ) { |
810 | ::close( sStdout[0] ); | 810 | ::close( sStdout[0] ); |
811 | ::close( sStdout[1] ); | 811 | ::close( sStdout[1] ); |
812 | } | 812 | } |
813 | if ( comms & Stderr ) { | 813 | if ( comms & Stderr ) { |
814 | ::close( sStderr[0] ); | 814 | ::close( sStderr[0] ); |
815 | ::close( sStderr[1] ); | 815 | ::close( sStderr[1] ); |
816 | } | 816 | } |
817 | ::close( fd[0] ); | 817 | ::close( fd[0] ); |
818 | ::close( fd[1] ); | 818 | ::close( fd[1] ); |
819 | delete[] arglistQ; | 819 | delete[] arglistQ; |
820 | delete[] arglist; | 820 | delete[] arglist; |
821 | return FALSE; | 821 | return FALSE; |
822 | } | 822 | } |
823 | 823 | ||
824 | 824 | ||
825 | /*! | 825 | /*! |
826 | Asks the process to terminate. Processes can ignore this wish. If you want to | 826 | Asks the process to terminate. Processes can ignore this wish. If you want to |
827 | be sure that the process really terminates, you must use kill() instead. | 827 | be sure that the process really terminates, you must use kill() instead. |
828 | 828 | ||
829 | The slot returns immediately: it does not wait until the process has | 829 | The slot returns immediately: it does not wait until the process has |
830 | finished. When the process really exited, the signal processExited() is | 830 | finished. When the process really exited, the signal processExited() is |
831 | emitted. | 831 | emitted. |
832 | 832 | ||
833 | \sa kill() processExited() | 833 | \sa kill() processExited() |
834 | */ | 834 | */ |
835 | void QProcess::tryTerminate() const | 835 | void QProcess::tryTerminate() const |
836 | { | 836 | { |
837 | if ( d->proc != 0 ) | 837 | if ( d->proc != 0 ) |
838 | ::kill( d->proc->pid, SIGTERM ); | 838 | ::kill( d->proc->pid, SIGTERM ); |
839 | } | 839 | } |
840 | 840 | ||
841 | /*! | 841 | /*! |
842 | Terminates the process. This is not a safe way to end a process since the | 842 | Terminates the process. This is not a safe way to end a process since the |
843 | process will not be able to do cleanup. tryTerminate() is a safer way to do | 843 | process will not be able to do cleanup. tryTerminate() is a safer way to do |
844 | it, but processes might ignore a tryTerminate(). | 844 | it, but processes might ignore a tryTerminate(). |
845 | 845 | ||
846 | The nice way to end a process and to be sure that it is finished, is doing | 846 | The nice way to end a process and to be sure that it is finished, is doing |
847 | something like this: | 847 | something like this: |
848 | \code | 848 | \code |
849 | process->tryTerminate(); | 849 | process->tryTerminate(); |
850 | QTimer::singleShot( 5000, process, SLOT( kill() ) ); | 850 | QTimer::singleShot( 5000, process, SLOT( kill() ) ); |
851 | \endcode | 851 | \endcode |
852 | 852 | ||
853 | This tries to terminate the process the nice way. If the process is still | 853 | This tries to terminate the process the nice way. If the process is still |
854 | running after 5 seconds, it terminates the process the hard way. The timeout | 854 | running after 5 seconds, it terminates the process the hard way. The timeout |
855 | should be chosen depending on the time the process needs to do all the | 855 | should be chosen depending on the time the process needs to do all the |
856 | cleanup: use a higher value if the process is likely to do heavy computation | 856 | cleanup: use a higher value if the process is likely to do heavy computation |
857 | on cleanup. | 857 | on cleanup. |
858 | 858 | ||
859 | The slot returns immediately: it does not wait until the process has | 859 | The slot returns immediately: it does not wait until the process has |
860 | finished. When the process really exited, the signal processExited() is | 860 | finished. When the process really exited, the signal processExited() is |
861 | emitted. | 861 | emitted. |
862 | 862 | ||
863 | \sa tryTerminate() processExited() | 863 | \sa tryTerminate() processExited() |
864 | */ | 864 | */ |
865 | void QProcess::kill() const | 865 | void QProcess::kill() const |
866 | { | 866 | { |
867 | if ( d->proc != 0 ) | 867 | if ( d->proc != 0 ) |
868 | ::kill( d->proc->pid, SIGKILL ); | 868 | ::kill( d->proc->pid, SIGKILL ); |
869 | } | 869 | } |
870 | 870 | ||
871 | /*! | 871 | /*! |
872 | Returns TRUE if the process is running, otherwise FALSE. | 872 | Returns TRUE if the process is running, otherwise FALSE. |
873 | 873 | ||
874 | \sa normalExit() exitStatus() processExited() | 874 | \sa normalExit() exitStatus() processExited() |
875 | */ | 875 | */ |
876 | bool QProcess::isRunning() const | 876 | bool QProcess::isRunning() const |
877 | { | 877 | { |
878 | if ( d->exitValuesCalculated ) { | 878 | if ( d->exitValuesCalculated ) { |
879 | #if defined(QT_QPROCESS_DEBUG) | 879 | #if defined(QT_QPROCESS_DEBUG) |
880 | odebug << "QProcess::isRunning(): FALSE (already computed)" << oendl; | 880 | odebug << "QProcess::isRunning(): FALSE (already computed)" << oendl; |
881 | #endif | 881 | #endif |
882 | return FALSE; | 882 | return FALSE; |
883 | } | 883 | } |
884 | if ( d->proc == 0 ) | 884 | if ( d->proc == 0 ) |
885 | return FALSE; | 885 | return FALSE; |
886 | int status; | 886 | int status; |
887 | if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) | 887 | if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) |
888 | { | 888 | { |
889 | // compute the exit values | 889 | // compute the exit values |
890 | QProcess *that = (QProcess*)this; // mutable | 890 | QProcess *that = (QProcess*)this; // mutable |
891 | that->exitNormal = WIFEXITED( status ) != 0; | 891 | that->exitNormal = WIFEXITED( status ) != 0; |
892 | if ( exitNormal ) { | 892 | if ( exitNormal ) { |
893 | that->exitStat = (char)WEXITSTATUS( status ); | 893 | that->exitStat = (char)WEXITSTATUS( status ); |
894 | } | 894 | } |
895 | d->exitValuesCalculated = TRUE; | 895 | d->exitValuesCalculated = TRUE; |
896 | #if defined(QT_QPROCESS_DEBUG) | 896 | #if defined(QT_QPROCESS_DEBUG) |
897 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): FALSE" << oendl; | 897 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): FALSE" << oendl; |
898 | #endif | 898 | #endif |
899 | return FALSE; | 899 | return FALSE; |
900 | } | 900 | } |
901 | #if defined(QT_QPROCESS_DEBUG) | 901 | #if defined(QT_QPROCESS_DEBUG) |
902 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): TRUE" << oendl; | 902 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): TRUE" << oendl; |
903 | #endif | 903 | #endif |
904 | return TRUE; | 904 | return TRUE; |
905 | } | 905 | } |
906 | 906 | ||
907 | /*! | 907 | /*! |
908 | Writes the data \a buf to the standard input of the process. The process may | 908 | Writes the data \a buf to the standard input of the process. The process may |
909 | or may not read this data. | 909 | or may not read this data. |
910 | 910 | ||
911 | This function returns immediately; the QProcess class might write the data at | 911 | This function returns immediately; the QProcess class might write the data at |
912 | a later point (you have to enter the event loop for that). When all the data | 912 | a later point (you have to enter the event loop for that). When all the data |
913 | is written to the process, the signal wroteToStdin() is emitted. This does | 913 | is written to the process, the signal wroteToStdin() is emitted. This does |
914 | not mean that the process really read the data, since this class only detects | 914 | not mean that the process really read the data, since this class only detects |
915 | when it was able to write the data to the operating system. | 915 | when it was able to write the data to the operating system. |
916 | 916 | ||
917 | \sa wroteToStdin() closeStdin() readStdout() readStderr() | 917 | \sa wroteToStdin() closeStdin() readStdout() readStderr() |
918 | */ | 918 | */ |
919 | void QProcess::writeToStdin( const QByteArray& buf ) | 919 | void QProcess::writeToStdin( const QByteArray& buf ) |
920 | { | 920 | { |
921 | #if defined(QT_QPROCESS_DEBUG) | 921 | #if defined(QT_QPROCESS_DEBUG) |
922 | // odebug << "QProcess::writeToStdin(): write to stdin (" << d->socketStdin << ")" << oendl; | 922 | // odebug << "QProcess::writeToStdin(): write to stdin (" << d->socketStdin << ")" << oendl; |
923 | #endif | 923 | #endif |
924 | d->stdinBuf.enqueue( new QByteArray(buf) ); | 924 | d->stdinBuf.enqueue( new QByteArray(buf) ); |
925 | if ( d->notifierStdin != 0 ) | 925 | if ( d->notifierStdin != 0 ) |
926 | d->notifierStdin->setEnabled( TRUE ); | 926 | d->notifierStdin->setEnabled( TRUE ); |
927 | } | 927 | } |
928 | 928 | ||
929 | 929 | ||
930 | /*! | 930 | /*! |
931 | Closes standard input of the process. | 931 | Closes standard input of the process. |
932 | 932 | ||
933 | This function also deletes pending data that is not written to standard input | 933 | This function also deletes pending data that is not written to standard input |
934 | yet. | 934 | yet. |
935 | 935 | ||
936 | \sa wroteToStdin() | 936 | \sa wroteToStdin() |
937 | */ | 937 | */ |
938 | void QProcess::closeStdin() | 938 | void QProcess::closeStdin() |
939 | { | 939 | { |
940 | if ( d->proc == 0 ) | 940 | if ( d->proc == 0 ) |
941 | return; | 941 | return; |
942 | if ( d->proc->socketStdin !=0 ) { | 942 | if ( d->proc->socketStdin !=0 ) { |
943 | while ( !d->stdinBuf.isEmpty() ) { | 943 | while ( !d->stdinBuf.isEmpty() ) { |
944 | delete d->stdinBuf.dequeue(); | 944 | delete d->stdinBuf.dequeue(); |
945 | } | 945 | } |
946 | delete d->notifierStdin; | 946 | delete d->notifierStdin; |
947 | d->notifierStdin = 0; | 947 | d->notifierStdin = 0; |
948 | if ( ::close( d->proc->socketStdin ) != 0 ) { | 948 | if ( ::close( d->proc->socketStdin ) != 0 ) { |
949 | owarn << "Could not close stdin of child process" << oendl; | 949 | owarn << "Could not close stdin of child process" << oendl; |
950 | } | 950 | } |
951 | #if defined(QT_QPROCESS_DEBUG) | 951 | #if defined(QT_QPROCESS_DEBUG) |
952 | odebug << "QProcess::closeStdin(): stdin (" << d->proc->socketStdin << ") closed" << oendl; | 952 | odebug << "QProcess::closeStdin(): stdin (" << d->proc->socketStdin << ") closed" << oendl; |
953 | #endif | 953 | #endif |
954 | d->proc->socketStdin = 0; | 954 | d->proc->socketStdin = 0; |
955 | } | 955 | } |
956 | } | 956 | } |
957 | 957 | ||
958 | 958 | ||
959 | /* | 959 | /* |
960 | This private slot is called when the process has outputted data to either | 960 | This private slot is called when the process has outputted data to either |
961 | standard output or standard error. | 961 | standard output or standard error. |
962 | */ | 962 | */ |
963 | void QProcess::socketRead( int fd ) | 963 | void QProcess::socketRead( int fd ) |
964 | { | 964 | { |
965 | if ( d->socketReadCalled ) { | 965 | if ( d->socketReadCalled ) { |
966 | // the slots that are connected to the readyRead...() signals might | 966 | // the slots that are connected to the readyRead...() signals might |
967 | // trigger a recursive call of socketRead(). Avoid this since you get a | 967 | // trigger a recursive call of socketRead(). Avoid this since you get a |
968 | // blocking read otherwise. | 968 | // blocking read otherwise. |
969 | return; | 969 | return; |
970 | } | 970 | } |
971 | #if defined(QT_QPROCESS_DEBUG) | 971 | #if defined(QT_QPROCESS_DEBUG) |
972 | odebug << "QProcess::socketRead(): " << fd << "" << oendl; | 972 | odebug << "QProcess::socketRead(): " << fd << "" << oendl; |
973 | #endif | 973 | #endif |
974 | if ( fd == 0 ) | 974 | if ( fd == 0 ) |
975 | return; | 975 | return; |
976 | const int bufsize = 4096; | 976 | const int bufsize = 4096; |
977 | QByteArray *buffer = 0; | 977 | QByteArray *buffer = 0; |
978 | uint oldSize; | 978 | uint oldSize; |
979 | int n; | 979 | int n; |
980 | if ( fd == d->proc->socketStdout ) { | 980 | if ( fd == d->proc->socketStdout ) { |
981 | buffer = &d->bufStdout; | 981 | buffer = &d->bufStdout; |
982 | } else if ( fd == d->proc->socketStderr ) { | 982 | } else if ( fd == d->proc->socketStderr ) { |
983 | buffer = &d->bufStderr; | 983 | buffer = &d->bufStderr; |
984 | } else { | 984 | } else { |
985 | // this case should never happen, but just to be safe | 985 | // this case should never happen, but just to be safe |
986 | return; | 986 | return; |
987 | } | 987 | } |
988 | 988 | ||
989 | // read data | 989 | // read data |
990 | oldSize = buffer->size(); | 990 | oldSize = buffer->size(); |
991 | buffer->resize( oldSize + bufsize ); | 991 | buffer->resize( oldSize + bufsize ); |
992 | n = ::read( fd, buffer->data()+oldSize, bufsize ); | 992 | n = ::read( fd, buffer->data()+oldSize, bufsize ); |
993 | if ( n > 0 ) | 993 | if ( n > 0 ) |
994 | buffer->resize( oldSize + n ); | 994 | buffer->resize( oldSize + n ); |
995 | else | 995 | else |
996 | buffer->resize( oldSize ); | 996 | buffer->resize( oldSize ); |
997 | // eof or error? | 997 | // eof or error? |
998 | if ( n == 0 || n == -1 ) { | 998 | if ( n == 0 || n == -1 ) { |
999 | if ( fd == d->proc->socketStdout ) { | 999 | if ( fd == d->proc->socketStdout ) { |
1000 | #if defined(QT_QPROCESS_DEBUG) | 1000 | #if defined(QT_QPROCESS_DEBUG) |
1001 | odebug << "QProcess::socketRead(): stdout (" << fd << ") closed" << oendl; | 1001 | odebug << "QProcess::socketRead(): stdout (" << fd << ") closed" << oendl; |
1002 | #endif | 1002 | #endif |
1003 | d->notifierStdout->setEnabled( FALSE ); | 1003 | d->notifierStdout->setEnabled( FALSE ); |
1004 | delete d->notifierStdout; | 1004 | delete d->notifierStdout; |
1005 | d->notifierStdout = 0; | 1005 | d->notifierStdout = 0; |
1006 | ::close( d->proc->socketStdout ); | 1006 | ::close( d->proc->socketStdout ); |
1007 | d->proc->socketStdout = 0; | 1007 | d->proc->socketStdout = 0; |
1008 | return; | 1008 | return; |
1009 | } else if ( fd == d->proc->socketStderr ) { | 1009 | } else if ( fd == d->proc->socketStderr ) { |
1010 | #if defined(QT_QPROCESS_DEBUG) | 1010 | #if defined(QT_QPROCESS_DEBUG) |
1011 | odebug << "QProcess::socketRead(): stderr (" << fd << ") closed" << oendl; | 1011 | odebug << "QProcess::socketRead(): stderr (" << fd << ") closed" << oendl; |
1012 | #endif | 1012 | #endif |
1013 | d->notifierStderr->setEnabled( FALSE ); | 1013 | d->notifierStderr->setEnabled( FALSE ); |
1014 | delete d->notifierStderr; | 1014 | delete d->notifierStderr; |
1015 | d->notifierStderr = 0; | 1015 | d->notifierStderr = 0; |
1016 | ::close( d->proc->socketStderr ); | 1016 | ::close( d->proc->socketStderr ); |
1017 | d->proc->socketStderr = 0; | 1017 | d->proc->socketStderr = 0; |
1018 | return; | 1018 | return; |
1019 | } | 1019 | } |
1020 | } | 1020 | } |
1021 | // read all data that is available | 1021 | // read all data that is available |
1022 | while ( n == bufsize ) { | 1022 | while ( n == bufsize ) { |
1023 | oldSize = buffer->size(); | 1023 | oldSize = buffer->size(); |
1024 | buffer->resize( oldSize + bufsize ); | 1024 | buffer->resize( oldSize + bufsize ); |
1025 | n = ::read( fd, buffer->data()+oldSize, bufsize ); | 1025 | n = ::read( fd, buffer->data()+oldSize, bufsize ); |
1026 | if ( n > 0 ) | 1026 | if ( n > 0 ) |
1027 | buffer->resize( oldSize + n ); | 1027 | buffer->resize( oldSize + n ); |
1028 | else | 1028 | else |
1029 | buffer->resize( oldSize ); | 1029 | buffer->resize( oldSize ); |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | d->socketReadCalled = TRUE; | 1032 | d->socketReadCalled = TRUE; |
1033 | if ( fd == d->proc->socketStdout ) { | 1033 | if ( fd == d->proc->socketStdout ) { |
1034 | #if defined(QT_QPROCESS_DEBUG) | 1034 | #if defined(QT_QPROCESS_DEBUG) |
1035 | qDebug( "QProcess::socketRead(): %d bytes read from stdout (%d)", | 1035 | odebug << "QProcess::socketRead(): " << buffer->size()-oldSize << "bytes read from stdout (" |
1036 | buffer->size()-oldSize, fd ); | 1036 | << fd << ")" << oendl; |
1037 | #endif | 1037 | #endif |
1038 | emit readyReadStdout(); | 1038 | emit readyReadStdout(); |
1039 | } else if ( fd == d->proc->socketStderr ) { | 1039 | } else if ( fd == d->proc->socketStderr ) { |
1040 | #if defined(QT_QPROCESS_DEBUG) | 1040 | #if defined(QT_QPROCESS_DEBUG) |
1041 | qDebug( "QProcess::socketRead(): %d bytes read from stderr (%d)", | 1041 | odebug << "QProcess::socketRead(): " << buffer->size()-oldSize << " bytes read from stderr (" |
1042 | buffer->size()-oldSize, fd ); | 1042 | << fd << ")" << oendl; |
1043 | #endif | 1043 | #endif |
1044 | emit readyReadStderr(); | 1044 | emit readyReadStderr(); |
1045 | } | 1045 | } |
1046 | d->socketReadCalled = FALSE; | 1046 | d->socketReadCalled = FALSE; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | 1049 | ||
1050 | /* | 1050 | /* |
1051 | This private slot is called when the process tries to read data from standard | 1051 | This private slot is called when the process tries to read data from standard |
1052 | input. | 1052 | input. |
1053 | */ | 1053 | */ |
1054 | void QProcess::socketWrite( int fd ) | 1054 | void QProcess::socketWrite( int fd ) |
1055 | { | 1055 | { |
1056 | if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 ) | 1056 | if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 ) |
1057 | return; | 1057 | return; |
1058 | if ( d->stdinBuf.isEmpty() ) { | 1058 | if ( d->stdinBuf.isEmpty() ) { |
1059 | d->notifierStdin->setEnabled( FALSE ); | 1059 | d->notifierStdin->setEnabled( FALSE ); |
1060 | return; | 1060 | return; |
1061 | } | 1061 | } |
1062 | #if defined(QT_QPROCESS_DEBUG) | 1062 | #if defined(QT_QPROCESS_DEBUG) |
1063 | odebug << "QProcess::socketWrite(): write to stdin (" << fd << ")" << oendl; | 1063 | odebug << "QProcess::socketWrite(): write to stdin (" << fd << ")" << oendl; |
1064 | #endif | 1064 | #endif |
1065 | ssize_t ret = ::write( fd, | 1065 | ssize_t ret = ::write( fd, |
1066 | d->stdinBuf.head()->data() + d->stdinBufRead, | 1066 | d->stdinBuf.head()->data() + d->stdinBufRead, |
1067 | d->stdinBuf.head()->size() - d->stdinBufRead ); | 1067 | d->stdinBuf.head()->size() - d->stdinBufRead ); |
1068 | if ( ret > 0 ) | 1068 | if ( ret > 0 ) |
1069 | d->stdinBufRead += ret; | 1069 | d->stdinBufRead += ret; |
1070 | if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) { | 1070 | if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) { |
1071 | d->stdinBufRead = 0; | 1071 | d->stdinBufRead = 0; |
1072 | delete d->stdinBuf.dequeue(); | 1072 | delete d->stdinBuf.dequeue(); |
1073 | if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) | 1073 | if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) |
1074 | emit wroteToStdin(); | 1074 | emit wroteToStdin(); |
1075 | socketWrite( fd ); | 1075 | socketWrite( fd ); |
1076 | } | 1076 | } |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | /*! | 1079 | /*! |
1080 | \internal | 1080 | \internal |
1081 | Flushes standard input. This is useful if you want to use QProcess in a | 1081 | Flushes standard input. This is useful if you want to use QProcess in a |
1082 | synchronous manner. | 1082 | synchronous manner. |
1083 | 1083 | ||
1084 | This function should probably go into the public API. | 1084 | This function should probably go into the public API. |
1085 | */ | 1085 | */ |
1086 | void QProcess::flushStdin() | 1086 | void QProcess::flushStdin() |
1087 | { | 1087 | { |
1088 | socketWrite( d->proc->socketStdin ); | 1088 | socketWrite( d->proc->socketStdin ); |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | /* | 1091 | /* |
1092 | This private slot is only used under Windows (but moc does not know about #if | 1092 | This private slot is only used under Windows (but moc does not know about #if |
1093 | defined()). | 1093 | defined()). |
1094 | */ | 1094 | */ |
1095 | void QProcess::timeout() | 1095 | void QProcess::timeout() |
1096 | { | 1096 | { |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | 1099 | ||
1100 | /* | 1100 | /* |
1101 | This private function is used by connectNotify() and disconnectNotify() to | 1101 | This private function is used by connectNotify() and disconnectNotify() to |
1102 | change the value of ioRedirection (and related behaviour) | 1102 | change the value of ioRedirection (and related behaviour) |
1103 | */ | 1103 | */ |
1104 | void QProcess::setIoRedirection( bool value ) | 1104 | void QProcess::setIoRedirection( bool value ) |
1105 | { | 1105 | { |
1106 | ioRedirection = value; | 1106 | ioRedirection = value; |
1107 | if ( ioRedirection ) { | 1107 | if ( ioRedirection ) { |
1108 | if ( d->notifierStdout ) | 1108 | if ( d->notifierStdout ) |
1109 | d->notifierStdout->setEnabled( TRUE ); | 1109 | d->notifierStdout->setEnabled( TRUE ); |
1110 | if ( d->notifierStderr ) | 1110 | if ( d->notifierStderr ) |
1111 | d->notifierStderr->setEnabled( TRUE ); | 1111 | d->notifierStderr->setEnabled( TRUE ); |
1112 | } else { | 1112 | } else { |
1113 | if ( d->notifierStdout ) | 1113 | if ( d->notifierStdout ) |
1114 | d->notifierStdout->setEnabled( FALSE ); | 1114 | d->notifierStdout->setEnabled( FALSE ); |
1115 | if ( d->notifierStderr ) | 1115 | if ( d->notifierStderr ) |
1116 | d->notifierStderr->setEnabled( FALSE ); | 1116 | d->notifierStderr->setEnabled( FALSE ); |
1117 | } | 1117 | } |
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | /* | 1120 | /* |
1121 | This private function is used by connectNotify() and | 1121 | This private function is used by connectNotify() and |
1122 | disconnectNotify() to change the value of notifyOnExit (and related | 1122 | disconnectNotify() to change the value of notifyOnExit (and related |
1123 | behaviour) | 1123 | behaviour) |
1124 | */ | 1124 | */ |
1125 | void QProcess::setNotifyOnExit( bool value ) | 1125 | void QProcess::setNotifyOnExit( bool value ) |
1126 | { | 1126 | { |
1127 | notifyOnExit = value; | 1127 | notifyOnExit = value; |
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | /* | 1130 | /* |
1131 | This private function is used by connectNotify() and disconnectNotify() to | 1131 | This private function is used by connectNotify() and disconnectNotify() to |
1132 | change the value of wroteToStdinConnected (and related behaviour) | 1132 | change the value of wroteToStdinConnected (and related behaviour) |
1133 | */ | 1133 | */ |
1134 | void QProcess::setWroteStdinConnected( bool value ) | 1134 | void QProcess::setWroteStdinConnected( bool value ) |
1135 | { | 1135 | { |
1136 | wroteToStdinConnected = value; | 1136 | wroteToStdinConnected = value; |
1137 | } | 1137 | } |
1138 | 1138 | ||
1139 | /*! \enum QProcess::PID | 1139 | /*! \enum QProcess::PID |
1140 | \internal | 1140 | \internal |
1141 | */ | 1141 | */ |
1142 | /*! | 1142 | /*! |
1143 | Returns platform dependent information about the process. This can be used | 1143 | Returns platform dependent information about the process. This can be used |
1144 | together with platform specific system calls. | 1144 | together with platform specific system calls. |
1145 | 1145 | ||
1146 | Under Unix the return value is the PID of the process, or -1 if no process is | 1146 | Under Unix the return value is the PID of the process, or -1 if no process is |
1147 | belonging to this object. | 1147 | belonging to this object. |
1148 | 1148 | ||
1149 | Under Windows it is a pointer to the \c PROCESS_INFORMATION struct, or 0 if | 1149 | Under Windows it is a pointer to the \c PROCESS_INFORMATION struct, or 0 if |
1150 | no process is belonging to this object. | 1150 | no process is belonging to this object. |
1151 | */ | 1151 | */ |
1152 | QProcess::PID QProcess::processIdentifier() | 1152 | QProcess::PID QProcess::processIdentifier() |
1153 | { | 1153 | { |
1154 | if ( d->proc == 0 ) | 1154 | if ( d->proc == 0 ) |
1155 | return -1; | 1155 | return -1; |
1156 | return d->proc->pid; | 1156 | return d->proc->pid; |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | int QProcess::priority() const | 1159 | int QProcess::priority() const |
1160 | { | 1160 | { |
1161 | if ( d->proc ) | 1161 | if ( d->proc ) |
1162 | return getpriority(PRIO_PROCESS,d->proc->pid); | 1162 | return getpriority(PRIO_PROCESS,d->proc->pid); |
1163 | return 0; | 1163 | return 0; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | void QProcess::setPriority(int p) | 1166 | void QProcess::setPriority(int p) |
1167 | { | 1167 | { |
1168 | if ( d->proc ) | 1168 | if ( d->proc ) |
1169 | setpriority(PRIO_PROCESS,d->proc->pid,p); | 1169 | setpriority(PRIO_PROCESS,d->proc->pid,p); |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | 1172 | ||
1173 | #endif // QT_NO_PROCESS | 1173 | #endif // QT_NO_PROCESS |
diff --git a/core/launcher/screensaver.cpp b/core/launcher/screensaver.cpp index a7d23c4..f818d62 100644 --- a/core/launcher/screensaver.cpp +++ b/core/launcher/screensaver.cpp | |||
@@ -1,328 +1,332 @@ | |||
1 | 1 | ||
2 | #include "screensaver.h" | 2 | #include "screensaver.h" |
3 | 3 | ||
4 | #include <qpe/config.h> | 4 | #include <qpe/config.h> |
5 | #include <qpe/network.h> | 5 | #include <qpe/network.h> |
6 | 6 | ||
7 | #include <opie2/odevice.h> | 7 | #include <opie2/odevice.h> |
8 | #include <opie2/odebug.h> | ||
8 | 9 | ||
9 | 10 | ||
10 | using namespace Opie::Core; | 11 | using namespace Opie::Core; |
11 | 12 | ||
12 | 13 | ||
13 | 14 | ||
14 | OpieScreenSaver::OpieScreenSaver ( ) | 15 | OpieScreenSaver::OpieScreenSaver ( ) |
15 | : QObject ( 0, "screensaver" ), QWSScreenSaver ( ) | 16 | : QObject ( 0, "screensaver" ), QWSScreenSaver ( ) |
16 | { | 17 | { |
17 | m_disable_suspend = 100; | 18 | m_disable_suspend = 100; |
18 | m_enable_dim = false; | 19 | m_enable_dim = false; |
19 | m_enable_lightoff = false; | 20 | m_enable_lightoff = false; |
20 | m_enable_suspend = false; | 21 | m_enable_suspend = false; |
21 | m_onlylcdoff = false; | 22 | m_onlylcdoff = false; |
22 | 23 | ||
23 | m_enable_dim_ac = false; | 24 | m_enable_dim_ac = false; |
24 | m_enable_lightoff_ac = false; | 25 | m_enable_lightoff_ac = false; |
25 | m_enable_suspend_ac = false; | 26 | m_enable_suspend_ac = false; |
26 | m_onlylcdoff_ac = false; | 27 | m_onlylcdoff_ac = false; |
27 | 28 | ||
28 | m_use_light_sensor = false; | 29 | m_use_light_sensor = false; |
29 | m_backlight_sensor = -1; | 30 | m_backlight_sensor = -1; |
30 | ::memset ( m_sensordata, 0xff, LS_Count * sizeof( m_sensordata [0] )); | 31 | ::memset ( m_sensordata, 0xff, LS_Count * sizeof( m_sensordata [0] )); |
31 | 32 | ||
32 | m_lcd_status = true; | 33 | m_lcd_status = true; |
33 | 34 | ||
34 | m_backlight_normal = -1; | 35 | m_backlight_normal = -1; |
35 | m_backlight_current = -1; | 36 | m_backlight_current = -1; |
36 | m_backlight_forcedoff = false; | 37 | m_backlight_forcedoff = false; |
37 | 38 | ||
38 | m_on_ac = false; | 39 | m_on_ac = false; |
39 | 40 | ||
40 | m_level = -1; | 41 | m_level = -1; |
41 | 42 | ||
42 | // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off) | 43 | // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off) |
43 | ODevice::inst ( )-> setDisplayStatus ( true ); | 44 | ODevice::inst ( )-> setDisplayStatus ( true ); |
44 | setBacklight ( -1 ); | 45 | setBacklight ( -1 ); |
45 | } | 46 | } |
46 | 47 | ||
47 | 48 | ||
48 | /** | 49 | /** |
49 | * Stops the screen saver | 50 | * Stops the screen saver |
50 | */ | 51 | */ |
51 | void OpieScreenSaver::restore() | 52 | void OpieScreenSaver::restore() |
52 | { | 53 | { |
53 | m_level = -1; | 54 | m_level = -1; |
54 | 55 | ||
55 | if ( !m_lcd_status ) { // We must have turned it off | 56 | if ( !m_lcd_status ) { // We must have turned it off |
56 | ODevice::inst ( ) -> setDisplayStatus ( true ); | 57 | ODevice::inst ( ) -> setDisplayStatus ( true ); |
57 | m_lcd_status = true; | 58 | m_lcd_status = true; |
58 | } | 59 | } |
59 | 60 | ||
60 | setBacklightInternal ( -1 ); | 61 | setBacklightInternal ( -1 ); |
61 | } | 62 | } |
62 | 63 | ||
63 | 64 | ||
64 | /** | 65 | /** |
65 | * Starts the screen saver | 66 | * Starts the screen saver |
66 | * | 67 | * |
67 | * @param level what level of screen saving should happen (0=lowest non-off, 1=off, | 68 | * @param level what level of screen saving should happen (0=lowest non-off, 1=off, |
68 | * 2=suspend whole machine) | 69 | * 2=suspend whole machine) |
69 | * @returns true on success | 70 | * @returns true on success |
70 | */ | 71 | */ |
71 | bool OpieScreenSaver::save( int level ) | 72 | bool OpieScreenSaver::save( int level ) |
72 | { | 73 | { |
73 | m_level = level; | 74 | m_level = level; |
74 | 75 | ||
75 | switch ( level ) { | 76 | switch ( level ) { |
76 | case 0: | 77 | case 0: |
77 | if (( m_on_ac && m_enable_dim_ac ) || | 78 | if (( m_on_ac && m_enable_dim_ac ) || |
78 | ( !m_on_ac && m_enable_dim )) { | 79 | ( !m_on_ac && m_enable_dim )) { |
79 | if (( m_disable_suspend > 0 ) && ( m_backlight_current > 1 ) && !m_use_light_sensor ) | 80 | if (( m_disable_suspend > 0 ) && ( m_backlight_current > 1 ) && !m_use_light_sensor ) |
80 | setBacklightInternal ( 1 ); // lowest non-off | 81 | setBacklightInternal ( 1 ); // lowest non-off |
81 | } | 82 | } |
82 | return true; | 83 | return true; |
83 | break; | 84 | break; |
84 | 85 | ||
85 | case 1: | 86 | case 1: |
86 | if (( m_on_ac && m_enable_lightoff_ac ) || | 87 | if (( m_on_ac && m_enable_lightoff_ac ) || |
87 | ( !m_on_ac && m_enable_lightoff )) { | 88 | ( !m_on_ac && m_enable_lightoff )) { |
88 | if ( m_disable_suspend > 1 ) | 89 | if ( m_disable_suspend > 1 ) |
89 | setBacklightInternal ( 0 ); // off | 90 | setBacklightInternal ( 0 ); // off |
90 | } | 91 | } |
91 | return true; | 92 | return true; |
92 | break; | 93 | break; |
93 | 94 | ||
94 | case 2: | 95 | case 2: |
95 | if (( m_on_ac && !m_enable_suspend_ac ) || | 96 | if (( m_on_ac && !m_enable_suspend_ac ) || |
96 | ( !m_on_ac && !m_enable_suspend )) { | 97 | ( !m_on_ac && !m_enable_suspend )) { |
97 | return true; | 98 | return true; |
98 | } | 99 | } |
99 | 100 | ||
100 | if (( m_on_ac && m_onlylcdoff_ac ) || | 101 | if (( m_on_ac && m_onlylcdoff_ac ) || |
101 | ( !m_on_ac && m_onlylcdoff )) { | 102 | ( !m_on_ac && m_onlylcdoff )) { |
102 | ODevice::inst ( ) -> setDisplayStatus ( false ); | 103 | ODevice::inst ( ) -> setDisplayStatus ( false ); |
103 | m_lcd_status = false; | 104 | m_lcd_status = false; |
104 | return true; | 105 | return true; |
105 | } | 106 | } |
106 | 107 | ||
107 | // We're going to suspend the whole machine | 108 | // We're going to suspend the whole machine |
108 | 109 | ||
109 | if (( m_disable_suspend > 2 ) && !Network::networkOnline ( )) { | 110 | if (( m_disable_suspend > 2 ) && !Network::networkOnline ( )) { |
110 | // TODO: why is this key F34 hard coded? -- schurig | 111 | // TODO: why is this key F34 hard coded? -- schurig |
111 | // Does this now only work an devices with a ODevice::filter? | 112 | // Does this now only work an devices with a ODevice::filter? |
112 | QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); | 113 | QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); |
113 | return true; | 114 | return true; |
114 | } | 115 | } |
115 | 116 | ||
116 | break; | 117 | break; |
117 | } | 118 | } |
118 | return false; | 119 | return false; |
119 | } | 120 | } |
120 | 121 | ||
121 | 122 | ||
122 | /** | 123 | /** |
123 | * Set intervals in seconds for automatic dimming, light off and suspend | 124 | * Set intervals in seconds for automatic dimming, light off and suspend |
124 | * | 125 | * |
125 | * This function also sets the member variables m_m_enable_dim[_ac], | 126 | * This function also sets the member variables m_m_enable_dim[_ac], |
126 | * m_enable_lightoff[_ac], m_enable_suspend[_ac], m_onlylcdoff[_ac] | 127 | * m_enable_lightoff[_ac], m_enable_suspend[_ac], m_onlylcdoff[_ac] |
127 | * | 128 | * |
128 | * @param dim time in seconds to dim, -1 to read value from config file, | 129 | * @param dim time in seconds to dim, -1 to read value from config file, |
129 | * 0 to disable | 130 | * 0 to disable |
130 | * @param lightoff time in seconds to turn LCD backlight off, -1 to | 131 | * @param lightoff time in seconds to turn LCD backlight off, -1 to |
131 | * read value from config file, 0 to disable | 132 | * read value from config file, 0 to disable |
132 | * @param suspend time in seconds to do an APM suspend, -1 to | 133 | * @param suspend time in seconds to do an APM suspend, -1 to |
133 | * read value from config file, 0 to disable | 134 | * read value from config file, 0 to disable |
134 | */ | 135 | */ |
135 | void OpieScreenSaver::setIntervals ( int dim, int lightoff, int suspend ) | 136 | void OpieScreenSaver::setIntervals ( int dim, int lightoff, int suspend ) |
136 | { | 137 | { |
137 | Config config ( "apm" ); | 138 | Config config ( "apm" ); |
138 | config. setGroup ( m_on_ac ? "AC" : "Battery" ); | 139 | config. setGroup ( m_on_ac ? "AC" : "Battery" ); |
139 | 140 | ||
140 | int v[ 4 ]; | 141 | int v[ 4 ]; |
141 | if ( dim < 0 ) | 142 | if ( dim < 0 ) |
142 | dim = config. readNumEntry ( "Dim", m_on_ac ? 60 : 30 ); | 143 | dim = config. readNumEntry ( "Dim", m_on_ac ? 60 : 30 ); |
143 | if ( lightoff < 0 ) | 144 | if ( lightoff < 0 ) |
144 | lightoff = config. readNumEntry ( "LightOff", m_on_ac ? 120 : 20 ); | 145 | lightoff = config. readNumEntry ( "LightOff", m_on_ac ? 120 : 20 ); |
145 | if ( suspend < 0 ) | 146 | if ( suspend < 0 ) |
146 | suspend = config. readNumEntry ( "Suspend", m_on_ac ? 0 : 60 ); | 147 | suspend = config. readNumEntry ( "Suspend", m_on_ac ? 0 : 60 ); |
147 | 148 | ||
148 | if ( m_on_ac ) { | 149 | if ( m_on_ac ) { |
149 | m_enable_dim_ac = ( dim > 0 ); | 150 | m_enable_dim_ac = ( dim > 0 ); |
150 | m_enable_lightoff_ac = ( lightoff > 0 ); | 151 | m_enable_lightoff_ac = ( lightoff > 0 ); |
151 | m_enable_suspend_ac = ( suspend > 0 ); | 152 | m_enable_suspend_ac = ( suspend > 0 ); |
152 | m_onlylcdoff_ac = config.readBoolEntry ( "LcdOffOnly", false ); | 153 | m_onlylcdoff_ac = config.readBoolEntry ( "LcdOffOnly", false ); |
153 | } | 154 | } |
154 | else { | 155 | else { |
155 | m_enable_dim = ( dim > 0 ); | 156 | m_enable_dim = ( dim > 0 ); |
156 | m_enable_lightoff = ( lightoff > 0 ); | 157 | m_enable_lightoff = ( lightoff > 0 ); |
157 | m_enable_suspend = ( suspend > 0 ); | 158 | m_enable_suspend = ( suspend > 0 ); |
158 | m_onlylcdoff = config.readBoolEntry ( "LcdOffOnly", false ); | 159 | m_onlylcdoff = config.readBoolEntry ( "LcdOffOnly", false ); |
159 | } | 160 | } |
160 | 161 | ||
161 | //odebug << "screen saver intervals: " << dim << " " << lightoff << " " << suspend << "" << oendl; | 162 | //odebug << "screen saver intervals: " << dim << " " << lightoff << " " << suspend << "" << oendl; |
162 | 163 | ||
163 | v [ 0 ] = QMAX( 1000 * dim, 100 ); | 164 | v [ 0 ] = QMAX( 1000 * dim, 100 ); |
164 | v [ 1 ] = QMAX( 1000 * lightoff, 100 ); | 165 | v [ 1 ] = QMAX( 1000 * lightoff, 100 ); |
165 | v [ 2 ] = QMAX( 1000 * suspend, 100 ); | 166 | v [ 2 ] = QMAX( 1000 * suspend, 100 ); |
166 | v [ 3 ] = 0; | 167 | v [ 3 ] = 0; |
167 | 168 | ||
168 | if ( !dim && !lightoff && !suspend ) | 169 | if ( !dim && !lightoff && !suspend ) |
169 | QWSServer::setScreenSaverInterval( 0 ); | 170 | QWSServer::setScreenSaverInterval( 0 ); |
170 | else | 171 | else |
171 | QWSServer::setScreenSaverIntervals( v ); | 172 | QWSServer::setScreenSaverIntervals( v ); |
172 | } | 173 | } |
173 | 174 | ||
174 | 175 | ||
175 | /** | 176 | /** |
176 | * Set suspend time. Will read the dim and lcd-off times from the config file. | 177 | * Set suspend time. Will read the dim and lcd-off times from the config file. |
177 | * | 178 | * |
178 | * @param suspend time in seconds to go into APM suspend, -1 to | 179 | * @param suspend time in seconds to go into APM suspend, -1 to |
179 | * read value from config file, 0 to disable | 180 | * read value from config file, 0 to disable |
180 | */ | 181 | */ |
181 | void OpieScreenSaver::setInterval ( int interval ) | 182 | void OpieScreenSaver::setInterval ( int interval ) |
182 | { | 183 | { |
183 | setIntervals ( -1, -1, interval ); | 184 | setIntervals ( -1, -1, interval ); |
184 | } | 185 | } |
185 | 186 | ||
186 | 187 | ||
187 | void OpieScreenSaver::setMode ( int mode ) | 188 | void OpieScreenSaver::setMode ( int mode ) |
188 | { | 189 | { |
189 | if ( mode > m_disable_suspend ) | 190 | if ( mode > m_disable_suspend ) |
190 | setInterval ( -1 ); | 191 | setInterval ( -1 ); |
191 | m_disable_suspend = mode; | 192 | m_disable_suspend = mode; |
192 | } | 193 | } |
193 | 194 | ||
194 | 195 | ||
195 | /** | 196 | /** |
196 | * Set display brightness | 197 | * Set display brightness |
197 | * | 198 | * |
198 | * Get's default values for backlight, contrast and light sensor from config file. | 199 | * Get's default values for backlight, contrast and light sensor from config file. |
199 | * | 200 | * |
200 | * @param bright desired brighness (-1 to use automatic sensor data or value | 201 | * @param bright desired brighness (-1 to use automatic sensor data or value |
201 | * from config file, -2 to toggle backlight on and off, -3 to | 202 | * from config file, -2 to toggle backlight on and off, -3 to |
202 | * force backlight off) | 203 | * force backlight off) |
203 | */ | 204 | */ |
204 | void OpieScreenSaver::setBacklight ( int bright ) | 205 | void OpieScreenSaver::setBacklight ( int bright ) |
205 | { | 206 | { |
206 | // Read from config | 207 | // Read from config |
207 | Config config ( "apm" ); | 208 | Config config ( "apm" ); |
208 | config. setGroup ( m_on_ac ? "AC" : "Battery" ); | 209 | config. setGroup ( m_on_ac ? "AC" : "Battery" ); |
209 | m_backlight_normal = config. readNumEntry ( "Brightness", m_on_ac ? 255 : 127 ); | 210 | m_backlight_normal = config. readNumEntry ( "Brightness", m_on_ac ? 255 : 127 ); |
210 | int contrast = config. readNumEntry ( "Contrast", 127); | 211 | int contrast = config. readNumEntry ( "Contrast", 127); |
211 | m_use_light_sensor = config. readBoolEntry ( "LightSensor", false ); | 212 | m_use_light_sensor = config. readBoolEntry ( "LightSensor", false ); |
212 | 213 | ||
213 | //qDebug ( "setBacklight: %d (norm: %d) (ls: %d)", bright, m_backlight_normal, m_use_light_sensor ? 1 : 0 ); | 214 | //odebug << "setBacklight: " << bright << " (norm: " << m_backlight_normal << ") (ls: " |
214 | 215 | // << ( m_use_light_sensor ? 1 : 0 ) << ")" << oendl; | |
215 | killTimers ( ); | 216 | |
216 | if (( bright < 0 ) && m_use_light_sensor ) { | 217 | killTimers ( ); |
217 | QStringList sl = config. readListEntry ( "LightSensorData", ';' ); | 218 | if (( bright < 0 ) && m_use_light_sensor ) { |
218 | 219 | QStringList sl = config. readListEntry ( "LightSensorData", ';' ); | |
219 | m_sensordata [LS_SensorMin] = 40; | 220 | |
220 | m_sensordata [LS_SensorMax] = 215; | 221 | m_sensordata [LS_SensorMin] = 40; |
221 | m_sensordata [LS_LightMin] = 1; | 222 | m_sensordata [LS_SensorMax] = 215; |
222 | m_sensordata [LS_LightMax] = 255; | 223 | m_sensordata [LS_LightMin] = 1; |
223 | m_sensordata [LS_Steps] = 12; | 224 | m_sensordata [LS_LightMax] = 255; |
224 | m_sensordata [LS_Interval] = 2000; | 225 | m_sensordata [LS_Steps] = 12; |
225 | 226 | m_sensordata [LS_Interval] = 2000; | |
226 | for ( uint i = 0; i < LS_Count; i++ ) { | 227 | |
227 | if ( i < sl. count ( )) | 228 | for ( uint i = 0; i < LS_Count; i++ ) { |
228 | m_sensordata [i] = sl [i]. toInt ( ); | 229 | if ( i < sl. count ( )) |
229 | } | 230 | m_sensordata [i] = sl [i]. toInt ( ); |
230 | if ( m_sensordata [LS_Steps] < 2 ) // sanity check to avoid SIGFPE | 231 | } |
231 | m_sensordata [LS_Steps] = 2; | 232 | if ( m_sensordata [LS_Steps] < 2 ) // sanity check to avoid SIGFPE |
232 | 233 | m_sensordata [LS_Steps] = 2; | |
233 | timerEvent ( 0 ); | 234 | |
234 | startTimer ( m_sensordata [LS_Interval] ); | 235 | timerEvent ( 0 ); |
235 | } | 236 | startTimer ( m_sensordata [LS_Interval] ); |
236 | 237 | } | |
237 | setBacklightInternal ( bright ); | 238 | |
238 | ODevice::inst ( )-> setDisplayContrast(contrast); | 239 | setBacklightInternal ( bright ); |
240 | ODevice::inst ( )-> setDisplayContrast(contrast); | ||
239 | } | 241 | } |
240 | 242 | ||
241 | 243 | ||
242 | /** | 244 | /** |
243 | * Internal brightness setting method | 245 | * Internal brightness setting method |
244 | * | 246 | * |
245 | * Get's default values for backlight and light sensor from config file. | 247 | * Get's default values for backlight and light sensor from config file. |
246 | * | 248 | * |
247 | * @param bright desired brighness (-1 to use automatic sensor data or value | 249 | * @param bright desired brighness (-1 to use automatic sensor data or value |
248 | * from config file, -2 to toggle backlight on and off, -3 to | 250 | * from config file, -2 to toggle backlight on and off, -3 to |
249 | * force backlight off) | 251 | * force backlight off) |
250 | */ | 252 | */ |
251 | void OpieScreenSaver::setBacklightInternal ( int bright ) | 253 | void OpieScreenSaver::setBacklightInternal ( int bright ) |
252 | { | 254 | { |
253 | if ( bright == -3 ) { | 255 | if ( bright == -3 ) { |
254 | // Forced on | 256 | // Forced on |
255 | m_backlight_forcedoff = false; | 257 | m_backlight_forcedoff = false; |
256 | bright = -1; | 258 | bright = -1; |
257 | } | 259 | } |
258 | if ( m_backlight_forcedoff && bright != -2 ) | 260 | if ( m_backlight_forcedoff && bright != -2 ) |
259 | return ; | 261 | return ; |
260 | if ( bright == -2 ) { | 262 | if ( bright == -2 ) { |
261 | // Toggle between off and on | 263 | // Toggle between off and on |
262 | bright = m_backlight_current ? 0 : -1; | 264 | bright = m_backlight_current ? 0 : -1; |
263 | m_backlight_forcedoff = !bright; | 265 | m_backlight_forcedoff = !bright; |
264 | } | 266 | } |
265 | if ( bright == -1 ) | 267 | if ( bright == -1 ) |
266 | bright = m_use_light_sensor ? m_backlight_sensor : m_backlight_normal; | 268 | bright = m_use_light_sensor ? m_backlight_sensor : m_backlight_normal; |
267 | 269 | ||
268 | if ( bright != m_backlight_current ) { | 270 | if ( bright != m_backlight_current ) { |
269 | ODevice::inst ( )-> setDisplayBrightness ( bright ); | 271 | ODevice::inst ( )-> setDisplayBrightness ( bright ); |
270 | m_backlight_current = bright; | 272 | m_backlight_current = bright; |
271 | } | 273 | } |
272 | } | 274 | } |
273 | 275 | ||
274 | 276 | ||
275 | /** | 277 | /** |
276 | * Timer event used for automatic setting the backlight according to a light sensor | 278 | * Timer event used for automatic setting the backlight according to a light sensor |
277 | * and to set the default brightness | 279 | * and to set the default brightness |
278 | */ | 280 | */ |
279 | void OpieScreenSaver::timerEvent ( QTimerEvent * ) | 281 | void OpieScreenSaver::timerEvent ( QTimerEvent * ) |
280 | { | 282 | { |
281 | int s = ODevice::inst ( )-> readLightSensor ( ) * 256 / ODevice::inst ( )-> lightSensorResolution ( ); | 283 | int s = ODevice::inst ( )-> readLightSensor ( ) * 256 / ODevice::inst ( )-> lightSensorResolution ( ); |
282 | 284 | ||
283 | if ( s < m_sensordata [LS_SensorMin] ) | 285 | if ( s < m_sensordata [LS_SensorMin] ) |
284 | m_backlight_sensor = m_sensordata [LS_LightMax]; | 286 | m_backlight_sensor = m_sensordata [LS_LightMax]; |
285 | else if ( s >= m_sensordata [LS_SensorMax] ) | 287 | else if ( s >= m_sensordata [LS_SensorMax] ) |
286 | m_backlight_sensor = m_sensordata [LS_LightMin]; | 288 | m_backlight_sensor = m_sensordata [LS_LightMin]; |
287 | else { | 289 | else { |
288 | int dx = m_sensordata [LS_SensorMax] - m_sensordata [LS_SensorMin]; | 290 | int dx = m_sensordata [LS_SensorMax] - m_sensordata [LS_SensorMin]; |
289 | int dy = m_sensordata [LS_LightMax] - m_sensordata [LS_LightMin]; | 291 | int dy = m_sensordata [LS_LightMax] - m_sensordata [LS_LightMin]; |
290 | 292 | ||
291 | int stepno = ( s - m_sensordata [LS_SensorMin] ) * m_sensordata [LS_Steps] / dx; // dx is never 0 | 293 | int stepno = ( s - m_sensordata [LS_SensorMin] ) * m_sensordata [LS_Steps] / dx; // dx is never 0 |
292 | 294 | ||
293 | m_backlight_sensor = m_sensordata [LS_LightMax] - dy * stepno / ( m_sensordata [LS_Steps] - 1 ); | 295 | m_backlight_sensor = m_sensordata [LS_LightMax] - dy * stepno / ( m_sensordata [LS_Steps] - 1 ); |
294 | } | 296 | } |
295 | 297 | ||
296 | //qDebug ( "f(%d) = %d [%d - %d] -> [%d - %d] / %d", s, m_backlight_sensor, m_sensordata [LS_SensorMin], m_sensordata [LS_SensorMax], m_sensordata [LS_LightMin], m_sensordata [LS_LightMax], m_sensordata [LS_Steps] ); | 298 | odebug << "f(" << s << ") = " << m_backlight_sensor << " [" << m_sensordata [LS_SensorMin] |
299 | << " - " << m_sensordata [LS_SensorMax] << " ] -> [" << m_sensordata [LS_LightMin] | ||
300 | << " - " << m_sensordata [LS_LightMax] << "] / " << m_sensordata [LS_Steps] << oendl; | ||
297 | 301 | ||
298 | if ( m_level <= 0 ) | 302 | if ( m_level <= 0 ) |
299 | setBacklightInternal ( -1 ); | 303 | setBacklightInternal ( -1 ); |
300 | } | 304 | } |
301 | 305 | ||
302 | 306 | ||
303 | /** | 307 | /** |
304 | * Like ODevice::setDisplayStatus(), but keep current state in m_lcd_status. | 308 | * Like ODevice::setDisplayStatus(), but keep current state in m_lcd_status. |
305 | */ | 309 | */ |
306 | void OpieScreenSaver::setDisplayState ( bool on ) | 310 | void OpieScreenSaver::setDisplayState ( bool on ) |
307 | { | 311 | { |
308 | if ( m_lcd_status != on ) { | 312 | if ( m_lcd_status != on ) { |
309 | ODevice::inst ( ) -> setDisplayStatus ( on ); | 313 | ODevice::inst ( ) -> setDisplayStatus ( on ); |
310 | m_lcd_status = on; | 314 | m_lcd_status = on; |
311 | } | 315 | } |
312 | } | 316 | } |
313 | 317 | ||
314 | 318 | ||
315 | /** | 319 | /** |
316 | * Set display to default ac/battery settings when power status changed. | 320 | * Set display to default ac/battery settings when power status changed. |
317 | */ | 321 | */ |
318 | void OpieScreenSaver::powerStatusChanged ( PowerStatus ps ) | 322 | void OpieScreenSaver::powerStatusChanged ( PowerStatus ps ) |
319 | { | 323 | { |
320 | bool newonac = ( ps. acStatus ( ) == PowerStatus::Online ); | 324 | bool newonac = ( ps. acStatus ( ) == PowerStatus::Online ); |
321 | 325 | ||
322 | if ( newonac != m_on_ac ) { | 326 | if ( newonac != m_on_ac ) { |
323 | m_on_ac = newonac; | 327 | m_on_ac = newonac; |
324 | setInterval ( -1 ); | 328 | setInterval ( -1 ); |
325 | setBacklight ( -1 ); | 329 | setBacklight ( -1 ); |
326 | restore ( ); | 330 | restore ( ); |
327 | } | 331 | } |
328 | } | 332 | } |
diff --git a/core/launcher/server.cpp b/core/launcher/server.cpp index b9fa1e5..950032d 100644 --- a/core/launcher/server.cpp +++ b/core/launcher/server.cpp | |||
@@ -33,697 +33,697 @@ | |||
33 | #include "applauncher.h" | 33 | #include "applauncher.h" |
34 | #if 0 | 34 | #if 0 |
35 | #include "suspendmonitor.h" | 35 | #include "suspendmonitor.h" |
36 | #endif | 36 | #endif |
37 | #include "documentlist.h" | 37 | #include "documentlist.h" |
38 | 38 | ||
39 | /* OPIE */ | 39 | /* OPIE */ |
40 | #include <opie2/odebug.h> | 40 | #include <opie2/odebug.h> |
41 | #include <opie2/odevicebutton.h> | 41 | #include <opie2/odevicebutton.h> |
42 | #include <opie2/odevice.h> | 42 | #include <opie2/odevice.h> |
43 | #include <qtopia/applnk.h> | 43 | #include <qtopia/applnk.h> |
44 | #include <qtopia/private/categories.h> | 44 | #include <qtopia/private/categories.h> |
45 | #include <qtopia/mimetype.h> | 45 | #include <qtopia/mimetype.h> |
46 | #include <qtopia/config.h> | 46 | #include <qtopia/config.h> |
47 | #include <qtopia/resource.h> | 47 | #include <qtopia/resource.h> |
48 | #include <qtopia/version.h> | 48 | #include <qtopia/version.h> |
49 | #include <qtopia/storage.h> | 49 | #include <qtopia/storage.h> |
50 | #include <qtopia/qcopenvelope_qws.h> | 50 | #include <qtopia/qcopenvelope_qws.h> |
51 | #include <qtopia/global.h> | 51 | #include <qtopia/global.h> |
52 | using namespace Opie::Core; | 52 | using namespace Opie::Core; |
53 | 53 | ||
54 | /* QT */ | 54 | /* QT */ |
55 | #include <qmainwindow.h> | 55 | #include <qmainwindow.h> |
56 | #include <qmessagebox.h> | 56 | #include <qmessagebox.h> |
57 | #include <qtimer.h> | 57 | #include <qtimer.h> |
58 | #include <qtextstream.h> | 58 | #include <qtextstream.h> |
59 | #include <qwindowsystem_qws.h> | 59 | #include <qwindowsystem_qws.h> |
60 | #include <qgfx_qws.h> | 60 | #include <qgfx_qws.h> |
61 | 61 | ||
62 | /* STD */ | 62 | /* STD */ |
63 | #include <unistd.h> | 63 | #include <unistd.h> |
64 | #include <stdlib.h> | 64 | #include <stdlib.h> |
65 | 65 | ||
66 | extern QRect qt_maxWindowRect; | 66 | extern QRect qt_maxWindowRect; |
67 | 67 | ||
68 | static QWidget *calibrate(bool) | 68 | static QWidget *calibrate(bool) |
69 | { | 69 | { |
70 | #ifdef Q_WS_QWS | 70 | #ifdef Q_WS_QWS |
71 | Calibrate *c = new Calibrate; | 71 | Calibrate *c = new Calibrate; |
72 | c->show(); | 72 | c->show(); |
73 | return c; | 73 | return c; |
74 | #else | 74 | #else |
75 | return 0; | 75 | return 0; |
76 | #endif | 76 | #endif |
77 | } | 77 | } |
78 | 78 | ||
79 | #define FACTORY(T) \ | 79 | #define FACTORY(T) \ |
80 | static QWidget *new##T( bool maximized ) { \ | 80 | static QWidget *new##T( bool maximized ) { \ |
81 | QWidget *w = new T( 0, 0, QWidget::WDestructiveClose | QWidget::WGroupLeader ); \ | 81 | QWidget *w = new T( 0, 0, QWidget::WDestructiveClose | QWidget::WGroupLeader ); \ |
82 | if ( maximized ) { \ | 82 | if ( maximized ) { \ |
83 | if ( qApp->desktop()->width() <= 350 ) { \ | 83 | if ( qApp->desktop()->width() <= 350 ) { \ |
84 | w->showMaximized(); \ | 84 | w->showMaximized(); \ |
85 | } else { \ | 85 | } else { \ |
86 | w->resize( QSize( 300, 300 ) ); \ | 86 | w->resize( QSize( 300, 300 ) ); \ |
87 | } \ | 87 | } \ |
88 | } \ | 88 | } \ |
89 | w->show(); \ | 89 | w->show(); \ |
90 | return w; \ | 90 | return w; \ |
91 | } | 91 | } |
92 | 92 | ||
93 | 93 | ||
94 | #ifdef SINGLE_APP | 94 | #ifdef SINGLE_APP |
95 | #define APP(a,b,c,d) FACTORY(b) | 95 | #define APP(a,b,c,d) FACTORY(b) |
96 | #include "apps.h" | 96 | #include "apps.h" |
97 | #undef APP | 97 | #undef APP |
98 | #endif // SINGLE_APP | 98 | #endif // SINGLE_APP |
99 | 99 | ||
100 | static Global::Command builtins[] = { | 100 | static Global::Command builtins[] = { |
101 | 101 | ||
102 | #ifdef SINGLE_APP | 102 | #ifdef SINGLE_APP |
103 | #define APP(a,b,c,d) { a, new##b, c, d }, | 103 | #define APP(a,b,c,d) { a, new##b, c, d }, |
104 | #include "apps.h" | 104 | #include "apps.h" |
105 | #undef APP | 105 | #undef APP |
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | /* FIXME defines need to be defined*/ | 108 | /* FIXME defines need to be defined*/ |
109 | #if !defined(OPIE_NO_BUILTIN_CALIBRATE) | 109 | #if !defined(OPIE_NO_BUILTIN_CALIBRATE) |
110 | { "calibrate", calibrate, 1, 0 }, // No tr | 110 | { "calibrate", calibrate, 1, 0 }, // No tr |
111 | #endif | 111 | #endif |
112 | #if !defined(OPIE_NO_BUILTIN_SHUTDOWN) | 112 | #if !defined(OPIE_NO_BUILTIN_SHUTDOWN) |
113 | { "shutdown", Global::shutdown, 1, 0 }, // No tr | 113 | { "shutdown", Global::shutdown, 1, 0 }, // No tr |
114 | // { "run", run, 1, 0 }, // No tr | 114 | // { "run", run, 1, 0 }, // No tr |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | { 0, calibrate,0, 0 }, | 117 | { 0, calibrate, 0, 0 }, |
118 | }; | 118 | }; |
119 | 119 | ||
120 | 120 | ||
121 | //--------------------------------------------------------------------------- | 121 | //--------------------------------------------------------------------------- |
122 | 122 | ||
123 | 123 | ||
124 | //=========================================================================== | 124 | //=========================================================================== |
125 | 125 | ||
126 | Server::Server() : | 126 | Server::Server() : |
127 | QWidget( 0, 0, WStyle_Tool | WStyle_Customize ), | 127 | QWidget( 0, 0, WStyle_Tool | WStyle_Customize ), |
128 | qcopBridge( 0 ), | 128 | qcopBridge( 0 ), |
129 | transferServer( 0 ), | 129 | transferServer( 0 ), |
130 | packageHandler( 0 ), | 130 | packageHandler( 0 ), |
131 | syncDialog( 0 ) | 131 | syncDialog( 0 ) |
132 | { | 132 | { |
133 | Global::setBuiltinCommands(builtins); | 133 | Global::setBuiltinCommands(builtins); |
134 | 134 | ||
135 | tid_xfer = 0; | 135 | tid_xfer = 0; |
136 | /* ### FIXME ### */ | 136 | /* ### FIXME ### */ |
137 | /* tid_today = startTimer(3600*2*1000);*/ | 137 | /* tid_today = startTimer(3600*2*1000);*/ |
138 | last_today_show = QDate::currentDate(); | 138 | last_today_show = QDate::currentDate(); |
139 | 139 | ||
140 | #if 0 | 140 | #if 0 |
141 | tsmMonitor = new TempScreenSaverMode(); | 141 | tsmMonitor = new TempScreenSaverMode(); |
142 | connect( tsmMonitor, SIGNAL(forceSuspend()), qApp, SIGNAL(power()) ); | 142 | connect( tsmMonitor, SIGNAL(forceSuspend()), qApp, SIGNAL(power()) ); |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | serverGui = new Launcher; | 145 | serverGui = new Launcher; |
146 | serverGui->createGUI(); | 146 | serverGui->createGUI(); |
147 | 147 | ||
148 | docList = new DocumentList( serverGui ); | 148 | docList = new DocumentList( serverGui ); |
149 | appLauncher = new AppLauncher(this); | 149 | appLauncher = new AppLauncher(this); |
150 | connect(appLauncher, SIGNAL(launched(int,const QString&)), this, SLOT(applicationLaunched(int,const QString&)) ); | 150 | connect(appLauncher, SIGNAL(launched(int,const QString&)), this, SLOT(applicationLaunched(int,const QString&)) ); |
151 | connect(appLauncher, SIGNAL(terminated(int,const QString&)), this, SLOT(applicationTerminated(int,const QString&)) ); | 151 | connect(appLauncher, SIGNAL(terminated(int,const QString&)), this, SLOT(applicationTerminated(int,const QString&)) ); |
152 | connect(appLauncher, SIGNAL(connected(const QString&)), this, SLOT(applicationConnected(const QString&)) ); | 152 | connect(appLauncher, SIGNAL(connected(const QString&)), this, SLOT(applicationConnected(const QString&)) ); |
153 | 153 | ||
154 | storage = new StorageInfo( this ); | 154 | storage = new StorageInfo( this ); |
155 | connect( storage, SIGNAL(disksChanged()), this, SLOT(storageChanged()) ); | 155 | connect( storage, SIGNAL(disksChanged()), this, SLOT(storageChanged()) ); |
156 | 156 | ||
157 | // start services | 157 | // start services |
158 | startTransferServer(); | 158 | startTransferServer(); |
159 | (void) new IrServer( this ); | 159 | (void) new IrServer( this ); |
160 | 160 | ||
161 | packageHandler = new PackageHandler( this ); | 161 | packageHandler = new PackageHandler( this ); |
162 | connect(qApp, SIGNAL(activate(const Opie::Core::ODeviceButton*,bool)), | 162 | connect(qApp, SIGNAL(activate(const Opie::Core::ODeviceButton*,bool)), |
163 | this,SLOT(activate(const Opie::Core::ODeviceButton*,bool))); | 163 | this,SLOT(activate(const Opie::Core::ODeviceButton*,bool))); |
164 | 164 | ||
165 | setGeometry( -10, -10, 9, 9 ); | 165 | setGeometry( -10, -10, 9, 9 ); |
166 | 166 | ||
167 | QCopChannel *channel = new QCopChannel("QPE/System", this); | 167 | QCopChannel *channel = new QCopChannel("QPE/System", this); |
168 | connect(channel, SIGNAL(received(const QCString&,const QByteArray&)), | 168 | connect(channel, SIGNAL(received(const QCString&,const QByteArray&)), |
169 | this, SLOT(systemMsg(const QCString&,const QByteArray&)) ); | 169 | this, SLOT(systemMsg(const QCString&,const QByteArray&)) ); |
170 | 170 | ||
171 | QCopChannel *tbChannel = new QCopChannel( "QPE/TaskBar", this ); | 171 | QCopChannel *tbChannel = new QCopChannel( "QPE/TaskBar", this ); |
172 | connect( tbChannel, SIGNAL(received(const QCString&,const QByteArray&)), | 172 | connect( tbChannel, SIGNAL(received(const QCString&,const QByteArray&)), |
173 | this, SLOT(receiveTaskBar(const QCString&,const QByteArray&)) ); | 173 | this, SLOT(receiveTaskBar(const QCString&,const QByteArray&)) ); |
174 | 174 | ||
175 | connect( qApp, SIGNAL(prepareForRestart()), this, SLOT(terminateServers()) ); | 175 | connect( qApp, SIGNAL(prepareForRestart()), this, SLOT(terminateServers()) ); |
176 | connect( qApp, SIGNAL(timeChanged()), this, SLOT(pokeTimeMonitors()) ); | 176 | connect( qApp, SIGNAL(timeChanged()), this, SLOT(pokeTimeMonitors()) ); |
177 | 177 | ||
178 | preloadApps(); | 178 | preloadApps(); |
179 | } | 179 | } |
180 | 180 | ||
181 | void Server::show() | 181 | void Server::show() |
182 | { | 182 | { |
183 | ServerApplication::login(TRUE); | 183 | ServerApplication::login(TRUE); |
184 | QWidget::show(); | 184 | QWidget::show(); |
185 | } | 185 | } |
186 | 186 | ||
187 | Server::~Server() | 187 | Server::~Server() |
188 | { | 188 | { |
189 | serverGui->destroyGUI(); | 189 | serverGui->destroyGUI(); |
190 | delete docList; | 190 | delete docList; |
191 | delete qcopBridge; | 191 | delete qcopBridge; |
192 | delete transferServer; | 192 | delete transferServer; |
193 | delete serverGui; | 193 | delete serverGui; |
194 | #if 0 | 194 | #if 0 |
195 | delete tsmMonitor; | 195 | delete tsmMonitor; |
196 | #endif | 196 | #endif |
197 | } | 197 | } |
198 | 198 | ||
199 | static bool hasVisibleWindow(const QString& clientname, bool partial) | 199 | static bool hasVisibleWindow(const QString& clientname, bool partial) |
200 | { | 200 | { |
201 | #ifdef QWS | 201 | #ifdef QWS |
202 | const QList<QWSWindow> &list = qwsServer->clientWindows(); | 202 | const QList<QWSWindow> &list = qwsServer->clientWindows(); |
203 | QWSWindow* w; | 203 | QWSWindow* w; |
204 | for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) { | 204 | for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) { |
205 | if ( w->client()->identity() == clientname ) { | 205 | if ( w->client()->identity() == clientname ) { |
206 | if ( partial && !w->isFullyObscured() ) | 206 | if ( partial && !w->isFullyObscured() ) |
207 | return TRUE; | 207 | return TRUE; |
208 | if ( !partial && !w->isFullyObscured() && !w->isPartiallyObscured() ) { | 208 | if ( !partial && !w->isFullyObscured() && !w->isPartiallyObscured() ) { |
209 | # if QT_VERSION < 0x030000 | 209 | # if QT_VERSION < 0x030000 |
210 | QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, | 210 | QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, |
211 | QSize(qt_screen->width(),qt_screen->height()) ); | 211 | QSize(qt_screen->width(),qt_screen->height()) ); |
212 | # else | 212 | # else |
213 | QRect mwr = qt_maxWindowRect; | 213 | QRect mwr = qt_maxWindowRect; |
214 | # endif | 214 | # endif |
215 | if ( mwr.contains(w->requested().boundingRect()) ) | 215 | if ( mwr.contains(w->requested().boundingRect()) ) |
216 | return TRUE; | 216 | return TRUE; |
217 | } | 217 | } |
218 | } | 218 | } |
219 | } | 219 | } |
220 | #endif | 220 | #endif |
221 | return FALSE; | 221 | return FALSE; |
222 | } | 222 | } |
223 | 223 | ||
224 | void Server::activate(const ODeviceButton* button, bool held) | 224 | void Server::activate(const ODeviceButton* button, bool held) |
225 | { | 225 | { |
226 | Global::terminateBuiltin("calibrate"); // No tr | 226 | Global::terminateBuiltin("calibrate"); // No tr |
227 | OQCopMessage om; | 227 | OQCopMessage om; |
228 | if ( held ) { | 228 | if ( held ) { |
229 | om = button->heldAction(); | 229 | om = button->heldAction(); |
230 | } else { | 230 | } else { |
231 | om = button->pressedAction(); | 231 | om = button->pressedAction(); |
232 | } | 232 | } |
233 | 233 | ||
234 | if ( om.channel() != "ignore" ) | 234 | if ( om.channel() != "ignore" ) |
235 | om.send(); | 235 | om.send(); |
236 | 236 | ||
237 | // A button with no action defined, will return a null ServiceRequest. Don't attempt | 237 | // A button with no action defined, will return a null ServiceRequest. Don't attempt |
238 | // to send/do anything with this as it will crash | 238 | // to send/do anything with this as it will crash |
239 | /* ### FIXME */ | 239 | /* ### FIXME */ |
240 | #if 0 | 240 | #if 0 |
241 | if ( !sr.isNull() ) { | 241 | if ( !sr.isNull() ) { |
242 | QString app = sr.app(); | 242 | QString app = sr.app(); |
243 | bool vis = hasVisibleWindow(app, app != "qpe"); | 243 | bool vis = hasVisibleWindow(app, app != "qpe"); |
244 | if ( sr.message() == "raise()" && vis ) { | 244 | if ( sr.message() == "raise()" && vis ) { |
245 | sr.setMessage("nextView()"); | 245 | sr.setMessage("nextView()"); |
246 | } else { | 246 | } else { |
247 | // "back door" | 247 | // "back door" |
248 | sr << (int)vis; | 248 | sr << (int)vis; |
249 | } | 249 | } |
250 | 250 | ||
251 | sr.send(); | 251 | sr.send(); |
252 | } | 252 | } |
253 | #endif | 253 | #endif |
254 | } | 254 | } |
255 | 255 | ||
256 | 256 | ||
257 | #ifdef Q_WS_QWS | 257 | #ifdef Q_WS_QWS |
258 | 258 | ||
259 | 259 | ||
260 | typedef struct KeyOverride { | 260 | typedef struct KeyOverride { |
261 | ushort scan_code; | 261 | ushort scan_code; |
262 | QWSServer::KeyMap map; | 262 | QWSServer::KeyMap map; |
263 | }; | 263 | }; |
264 | 264 | ||
265 | 265 | ||
266 | static const KeyOverride jp109keys[] = { | 266 | static const KeyOverride jp109keys[] = { |
267 | { 0x03, { Qt::Key_2, '2' , 0x22 , 0xffff } }, | 267 | { 0x03, { Qt::Key_2, '2' , 0x22 , 0xffff } }, |
268 | { 0x07, { Qt::Key_6, '6' , '&' , 0xffff } }, | 268 | { 0x07, { Qt::Key_6, '6' , '&' , 0xffff } }, |
269 | { 0x08, { Qt::Key_7, '7' , '\'' , 0xffff } }, | 269 | { 0x08, { Qt::Key_7, '7' , '\'' , 0xffff } }, |
270 | { 0x09, { Qt::Key_8, '8' , '(' , 0xffff } }, | 270 | { 0x09, { Qt::Key_8, '8' , '(' , 0xffff } }, |
271 | { 0x0a, { Qt::Key_9, '9' , ')' , 0xffff } }, | 271 | { 0x0a, { Qt::Key_9, '9' , ')' , 0xffff } }, |
272 | { 0x0b, { Qt::Key_0, '0' , 0xffff , 0xffff } }, | 272 | { 0x0b, { Qt::Key_0, '0' , 0xffff , 0xffff } }, |
273 | { 0x0c, { Qt::Key_Minus, '-' , '=' , 0xffff } }, | 273 | { 0x0c, { Qt::Key_Minus, '-' , '=' , 0xffff } }, |
274 | { 0x0d, { Qt::Key_AsciiCircum,'^' , '~' , '^' - 64 } }, | 274 | { 0x0d, { Qt::Key_AsciiCircum,'^' , '~' , '^' - 64 } }, |
275 | { 0x1a, { Qt::Key_At, '@' , '`' , 0xffff } }, | 275 | { 0x1a, { Qt::Key_At, '@' , '`' , 0xffff } }, |
276 | { 0x1b, { Qt::Key_BraceLeft, '[' , '{' , '[' - 64 } }, | 276 | { 0x1b, { Qt::Key_BraceLeft, '[' , '{' , '[' - 64 } }, |
277 | { 0x27, { Qt::Key_Semicolon, ';' , '+' , 0xffff } }, | 277 | { 0x27, { Qt::Key_Semicolon, ';' , '+' , 0xffff } }, |
278 | { 0x28, { Qt::Key_Colon, ':' , '*' , 0xffff } }, | 278 | { 0x28, { Qt::Key_Colon, ':' , '*' , 0xffff } }, |
279 | { 0x29, { Qt::Key_Zenkaku_Hankaku, 0xffff , 0xffff , 0xffff } }, | 279 | { 0x29, { Qt::Key_Zenkaku_Hankaku, 0xffff , 0xffff , 0xffff } }, |
280 | { 0x2b, { Qt::Key_BraceRight, ']' , '}' , ']'-64 } }, | 280 | { 0x2b, { Qt::Key_BraceRight, ']' , '}' , ']'-64 } }, |
281 | { 0x70, { Qt::Key_Hiragana_Katakana, 0xffff , 0xffff , 0xffff } }, | 281 | { 0x70, { Qt::Key_Hiragana_Katakana, 0xffff , 0xffff , 0xffff } }, |
282 | { 0x73, { Qt::Key_Backslash, '\\' , '_' , 0xffff } }, | 282 | { 0x73, { Qt::Key_Backslash, '\\' , '_' , 0xffff } }, |
283 | { 0x79, { Qt::Key_Henkan, 0xffff , 0xffff , 0xffff } }, | 283 | { 0x79, { Qt::Key_Henkan, 0xffff , 0xffff , 0xffff } }, |
284 | { 0x7b, { Qt::Key_Muhenkan, 0xffff , 0xffff , 0xffff } }, | 284 | { 0x7b, { Qt::Key_Muhenkan, 0xffff , 0xffff , 0xffff } }, |
285 | { 0x7d, { Qt::Key_yen, 0x00a5 , '|' , 0xffff } }, | 285 | { 0x7d, { Qt::Key_yen, 0x00a5 , '|' , 0xffff } }, |
286 | { 0x00, { 0, 0xffff , 0xffff , 0xffff } } | 286 | { 0x00, { 0, 0xffff , 0xffff , 0xffff } } |
287 | }; | 287 | }; |
288 | 288 | ||
289 | bool Server::setKeyboardLayout( const QString &kb ) | 289 | bool Server::setKeyboardLayout( const QString &kb ) |
290 | { | 290 | { |
291 | //quick demo version that can be extended | 291 | //quick demo version that can be extended |
292 | 292 | ||
293 | QIntDict<QWSServer::KeyMap> *om = 0; | 293 | QIntDict<QWSServer::KeyMap> *om = 0; |
294 | if ( kb == "us101" ) { // No tr | 294 | if ( kb == "us101" ) { // No tr |
295 | om = 0; | 295 | om = 0; |
296 | } else if ( kb == "jp109" ) { | 296 | } else if ( kb == "jp109" ) { |
297 | om = new QIntDict<QWSServer::KeyMap>(37); | 297 | om = new QIntDict<QWSServer::KeyMap>(37); |
298 | const KeyOverride *k = jp109keys; | 298 | const KeyOverride *k = jp109keys; |
299 | while ( k->scan_code ) { | 299 | while ( k->scan_code ) { |
300 | om->insert( k->scan_code, &k->map ); | 300 | om->insert( k->scan_code, &k->map ); |
301 | k++; | 301 | k++; |
302 | } | 302 | } |
303 | } | 303 | } |
304 | QWSServer::setOverrideKeys( om ); | 304 | QWSServer::setOverrideKeys( om ); |
305 | 305 | ||
306 | return TRUE; | 306 | return TRUE; |
307 | } | 307 | } |
308 | 308 | ||
309 | #endif | 309 | #endif |
310 | 310 | ||
311 | void Server::systemMsg(const QCString &msg, const QByteArray &data) | 311 | void Server::systemMsg(const QCString &msg, const QByteArray &data) |
312 | { | 312 | { |
313 | QDataStream stream( data, IO_ReadOnly ); | 313 | QDataStream stream( data, IO_ReadOnly ); |
314 | 314 | ||
315 | if ( msg == "securityChanged()" ) { | 315 | if ( msg == "securityChanged()" ) { |
316 | if ( transferServer ) | 316 | if ( transferServer ) |
317 | transferServer->authorizeConnections(); | 317 | transferServer->authorizeConnections(); |
318 | if ( qcopBridge ) | 318 | if ( qcopBridge ) |
319 | qcopBridge->authorizeConnections(); | 319 | qcopBridge->authorizeConnections(); |
320 | } | 320 | } |
321 | /* ### FIXME support TempScreenSaverMode */ | 321 | /* ### FIXME support TempScreenSaverMode */ |
322 | #if 0 | 322 | #if 0 |
323 | else if ( msg == "setTempScreenSaverMode(int,int)" ) { | 323 | else if ( msg == "setTempScreenSaverMode(int,int)" ) { |
324 | int mode, pid; | 324 | int mode, pid; |
325 | stream >> mode >> pid; | 325 | stream >> mode >> pid; |
326 | tsmMonitor->setTempMode(mode, pid); | 326 | tsmMonitor->setTempMode(mode, pid); |
327 | } | 327 | } |
328 | #endif | 328 | #endif |
329 | else if ( msg == "linkChanged(QString)" ) { | 329 | else if ( msg == "linkChanged(QString)" ) { |
330 | QString link; | 330 | QString link; |
331 | stream >> link; | 331 | stream >> link; |
332 | odebug << "desktop.cpp systemMsg -> linkchanged( " << link << " )" << oendl; | 332 | odebug << "desktop.cpp systemMsg -> linkchanged( " << link << " )" << oendl; |
333 | docList->linkChanged(link); | 333 | docList->linkChanged(link); |
334 | } else if ( msg == "serviceChanged(QString)" ) { | 334 | } else if ( msg == "serviceChanged(QString)" ) { |
335 | MimeType::updateApplications(); | 335 | MimeType::updateApplications(); |
336 | } else if ( msg == "mkdir(QString)" ) { | 336 | } else if ( msg == "mkdir(QString)" ) { |
337 | QString dir; | 337 | QString dir; |
338 | stream >> dir; | 338 | stream >> dir; |
339 | if ( !dir.isEmpty() ) | 339 | if ( !dir.isEmpty() ) |
340 | mkdir( dir ); | 340 | mkdir( dir ); |
341 | } else if ( msg == "rdiffGenSig(QString,QString)" ) { | 341 | } else if ( msg == "rdiffGenSig(QString,QString)" ) { |
342 | QString baseFile, sigFile; | 342 | QString baseFile, sigFile; |
343 | stream >> baseFile >> sigFile; | 343 | stream >> baseFile >> sigFile; |
344 | QRsync::generateSignature( baseFile, sigFile ); | 344 | QRsync::generateSignature( baseFile, sigFile ); |
345 | } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) { | 345 | } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) { |
346 | QString baseFile, sigFile, deltaFile; | 346 | QString baseFile, sigFile, deltaFile; |
347 | stream >> baseFile >> sigFile >> deltaFile; | 347 | stream >> baseFile >> sigFile >> deltaFile; |
348 | QRsync::generateDiff( baseFile, sigFile, deltaFile ); | 348 | QRsync::generateDiff( baseFile, sigFile, deltaFile ); |
349 | } else if ( msg == "rdiffApplyPatch(QString,QString)" ) { | 349 | } else if ( msg == "rdiffApplyPatch(QString,QString)" ) { |
350 | QString baseFile, deltaFile; | 350 | QString baseFile, deltaFile; |
351 | stream >> baseFile >> deltaFile; | 351 | stream >> baseFile >> deltaFile; |
352 | if ( !QFile::exists( baseFile ) ) { | 352 | if ( !QFile::exists( baseFile ) ) { |
353 | QFile f( baseFile ); | 353 | QFile f( baseFile ); |
354 | f.open( IO_WriteOnly ); | 354 | f.open( IO_WriteOnly ); |
355 | f.close(); | 355 | f.close(); |
356 | } | 356 | } |
357 | QRsync::applyDiff( baseFile, deltaFile ); | 357 | QRsync::applyDiff( baseFile, deltaFile ); |
358 | #ifndef QT_NO_COP | 358 | #ifndef QT_NO_COP |
359 | QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" ); | 359 | QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" ); |
360 | e << baseFile; | 360 | e << baseFile; |
361 | #endif | 361 | #endif |
362 | } else if ( msg == "rdiffCleanup()" ) { | 362 | } else if ( msg == "rdiffCleanup()" ) { |
363 | mkdir( "/tmp/rdiff" ); | 363 | mkdir( "/tmp/rdiff" ); |
364 | QDir dir; | 364 | QDir dir; |
365 | dir.setPath( "/tmp/rdiff" ); | 365 | dir.setPath( "/tmp/rdiff" ); |
366 | QStringList entries = dir.entryList(); | 366 | QStringList entries = dir.entryList(); |
367 | for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it ) | 367 | for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it ) |
368 | dir.remove( *it ); | 368 | dir.remove( *it ); |
369 | } else if ( msg == "sendHandshakeInfo()" ) { | 369 | } else if ( msg == "sendHandshakeInfo()" ) { |
370 | QString home = getenv( "HOME" ); | 370 | QString home = getenv( "HOME" ); |
371 | #ifndef QT_NO_COP | 371 | #ifndef QT_NO_COP |
372 | QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" ); | 372 | QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" ); |
373 | e << home; | 373 | e << home; |
374 | int locked = (int) ServerApplication::screenLocked(); | 374 | int locked = (int) ServerApplication::screenLocked(); |
375 | e << locked; | 375 | e << locked; |
376 | #endif | 376 | #endif |
377 | 377 | ||
378 | } | 378 | } |
379 | /* | 379 | /* |
380 | * QtopiaDesktop relies on the major number | 380 | * QtopiaDesktop relies on the major number |
381 | * to start with 1. We're at 0.9 | 381 | * to start with 1. We're at 0.9 |
382 | * so wee need to fake at least 1.4 to be able | 382 | * so wee need to fake at least 1.4 to be able |
383 | * to sync with QtopiaDesktop1.6 | 383 | * to sync with QtopiaDesktop1.6 |
384 | */ | 384 | */ |
385 | else if ( msg == "sendVersionInfo()" ) { | 385 | else if ( msg == "sendVersionInfo()" ) { |
386 | QCopEnvelope e( "QPE/Desktop", "versionInfo(QString,QString)" ); | 386 | QCopEnvelope e( "QPE/Desktop", "versionInfo(QString,QString)" ); |
387 | /* ### FIXME Architecture ### */ | 387 | /* ### FIXME Architecture ### */ |
388 | e << QString::fromLatin1("1.7") << "Uncustomized Device"; | 388 | e << QString::fromLatin1("1.7") << "Uncustomized Device"; |
389 | } else if ( msg == "sendCardInfo()" ) { | 389 | } else if ( msg == "sendCardInfo()" ) { |
390 | #ifndef QT_NO_COP | 390 | #ifndef QT_NO_COP |
391 | QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" ); | 391 | QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" ); |
392 | #endif | 392 | #endif |
393 | storage->update(); | 393 | storage->update(); |
394 | const QList<FileSystem> &fs = storage->fileSystems(); | 394 | const QList<FileSystem> &fs = storage->fileSystems(); |
395 | QListIterator<FileSystem> it ( fs ); | 395 | QListIterator<FileSystem> it ( fs ); |
396 | QString s; | 396 | QString s; |
397 | QString homeDir = getenv("HOME"); | 397 | QString homeDir = getenv("HOME"); |
398 | QString homeFs, homeFsPath; | 398 | QString homeFs, homeFsPath; |
399 | for ( ; it.current(); ++it ) { | 399 | for ( ; it.current(); ++it ) { |
400 | int k4 = (*it)->blockSize()/256; | 400 | int k4 = (*it)->blockSize()/256; |
401 | if ( (*it)->isRemovable() ) { | 401 | if ( (*it)->isRemovable() ) { |
402 | s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr | 402 | s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr |
403 | + QString::number( (*it)->availBlocks() * k4/4 ) | 403 | + QString::number( (*it)->availBlocks() * k4/4 ) |
404 | + "K " + (*it)->options() + ";"; | 404 | + "K " + (*it)->options() + ";"; |
405 | } else if ( homeDir.contains( (*it)->path() ) && | 405 | } else if ( homeDir.contains( (*it)->path() ) && |
406 | (*it)->path().length() > homeFsPath.length() ) { | 406 | (*it)->path().length() > homeFsPath.length() ) { |
407 | homeFsPath = (*it)->path(); | 407 | homeFsPath = (*it)->path(); |
408 | homeFs = | 408 | homeFs = |
409 | (*it)->name() + "=" + homeDir + "/Documents " // No tr | 409 | (*it)->name() + "=" + homeDir + "/Documents " // No tr |
410 | + QString::number( (*it)->availBlocks() * k4/4 ) | 410 | + QString::number( (*it)->availBlocks() * k4/4 ) |
411 | + "K " + (*it)->options() + ";"; | 411 | + "K " + (*it)->options() + ";"; |
412 | } | 412 | } |
413 | } | 413 | } |
414 | if ( !homeFs.isEmpty() ) | 414 | if ( !homeFs.isEmpty() ) |
415 | s += homeFs; | 415 | s += homeFs; |
416 | 416 | ||
417 | #ifndef QT_NO_COP | 417 | #ifndef QT_NO_COP |
418 | e << s; | 418 | e << s; |
419 | #endif | 419 | #endif |
420 | } else if ( msg == "sendSyncDate(QString)" ) { | 420 | } else if ( msg == "sendSyncDate(QString)" ) { |
421 | QString app; | 421 | QString app; |
422 | stream >> app; | 422 | stream >> app; |
423 | Config cfg( "qpe" ); | 423 | Config cfg( "qpe" ); |
424 | cfg.setGroup("SyncDate"); | 424 | cfg.setGroup("SyncDate"); |
425 | #ifndef QT_NO_COP | 425 | #ifndef QT_NO_COP |
426 | QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" ); | 426 | QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" ); |
427 | e << app << cfg.readEntry( app ); | 427 | e << app << cfg.readEntry( app ); |
428 | #endif | 428 | #endif |
429 | //qDebug("QPE/System sendSyncDate for %s: response %s", app.latin1(), | 429 | //odebug << "QPE/System sendSyncDate for " << app.latin1() << ": response " |
430 | //cfg.readEntry( app ).latin1() ); | 430 | // << cfg.readEntry( app ).latin1() << oendl; |
431 | } else if ( msg == "setSyncDate(QString,QString)" ) { | 431 | } else if ( msg == "setSyncDate(QString,QString)" ) { |
432 | QString app, date; | 432 | QString app, date; |
433 | stream >> app >> date; | 433 | stream >> app >> date; |
434 | Config cfg( "qpe" ); | 434 | Config cfg( "qpe" ); |
435 | cfg.setGroup("SyncDate"); | 435 | cfg.setGroup("SyncDate"); |
436 | cfg.writeEntry( app, date ); | 436 | cfg.writeEntry( app, date ); |
437 | //odebug << "setSyncDate(QString,QString) " << app << " " << date << "" << oendl; | 437 | //odebug << "setSyncDate(QString,QString) " << app << " " << date << "" << oendl; |
438 | } else if ( msg == "startSync(QString)" ) { | 438 | } else if ( msg == "startSync(QString)" ) { |
439 | QString what; | 439 | QString what; |
440 | stream >> what; | 440 | stream >> what; |
441 | delete syncDialog; | 441 | delete syncDialog; |
442 | syncDialog = new SyncDialog( this, what ); | 442 | syncDialog = new SyncDialog( this, what ); |
443 | syncDialog->show(); | 443 | syncDialog->show(); |
444 | connect( syncDialog, SIGNAL(cancel()), SLOT(cancelSync()) ); | 444 | connect( syncDialog, SIGNAL(cancel()), SLOT(cancelSync()) ); |
445 | } else if ( msg == "stopSync()") { | 445 | } else if ( msg == "stopSync()") { |
446 | delete syncDialog; | 446 | delete syncDialog; |
447 | syncDialog = 0; | 447 | syncDialog = 0; |
448 | } else if (msg == "restoreDone(QString)") { | 448 | } else if (msg == "restoreDone(QString)") { |
449 | docList->restoreDone(); | 449 | docList->restoreDone(); |
450 | } else if ( msg == "getAllDocLinks()" ) { | 450 | } else if ( msg == "getAllDocLinks()" ) { |
451 | docList->sendAllDocLinks(); | 451 | docList->sendAllDocLinks(); |
452 | } | 452 | } |
453 | #ifdef Q_WS_QWS | 453 | #ifdef Q_WS_QWS |
454 | else if ( msg == "setMouseProto(QString)" ) { | 454 | else if ( msg == "setMouseProto(QString)" ) { |
455 | QString mice; | 455 | QString mice; |
456 | stream >> mice; | 456 | stream >> mice; |
457 | setenv("QWS_MOUSE_PROTO",mice.latin1(),1); | 457 | setenv("QWS_MOUSE_PROTO",mice.latin1(),1); |
458 | qwsServer->openMouse(); | 458 | qwsServer->openMouse(); |
459 | } else if ( msg == "setKeyboard(QString)" ) { | 459 | } else if ( msg == "setKeyboard(QString)" ) { |
460 | QString kb; | 460 | QString kb; |
461 | stream >> kb; | 461 | stream >> kb; |
462 | setenv("QWS_KEYBOARD",kb.latin1(),1); | 462 | setenv("QWS_KEYBOARD",kb.latin1(),1); |
463 | qwsServer->openKeyboard(); | 463 | qwsServer->openKeyboard(); |
464 | 464 | ||
465 | } else if ( msg == "setKeyboardAutoRepeat(int,int)" ) { | 465 | } else if ( msg == "setKeyboardAutoRepeat(int,int)" ) { |
466 | int delay, period; | 466 | int delay, period; |
467 | stream >> delay >> period; | 467 | stream >> delay >> period; |
468 | qwsSetKeyboardAutoRepeat( delay, period ); | 468 | qwsSetKeyboardAutoRepeat( delay, period ); |
469 | Config cfg( "qpe" ); | 469 | Config cfg( "qpe" ); |
470 | cfg.setGroup("Keyboard"); | 470 | cfg.setGroup("Keyboard"); |
471 | cfg.writeEntry( "RepeatDelay", delay ); | 471 | cfg.writeEntry( "RepeatDelay", delay ); |
472 | cfg.writeEntry( "RepeatPeriod", period ); | 472 | cfg.writeEntry( "RepeatPeriod", period ); |
473 | } else if ( msg == "setKeyboardLayout(QString)" ) { | 473 | } else if ( msg == "setKeyboardLayout(QString)" ) { |
474 | QString kb; | 474 | QString kb; |
475 | stream >> kb; | 475 | stream >> kb; |
476 | setKeyboardLayout( kb ); | 476 | setKeyboardLayout( kb ); |
477 | Config cfg( "qpe" ); | 477 | Config cfg( "qpe" ); |
478 | cfg.setGroup("Keyboard"); | 478 | cfg.setGroup("Keyboard"); |
479 | cfg.writeEntry( "Layout", kb ); | 479 | cfg.writeEntry( "Layout", kb ); |
480 | } else if ( msg == "autoStart(QString)" ) { | 480 | } else if ( msg == "autoStart(QString)" ) { |
481 | QString appName; | 481 | QString appName; |
482 | stream >> appName; | 482 | stream >> appName; |
483 | Config cfg( "autostart" ); | 483 | Config cfg( "autostart" ); |
484 | cfg.setGroup( "AutoStart" ); | 484 | cfg.setGroup( "AutoStart" ); |
485 | if ( appName.compare("clear") == 0){ | 485 | if ( appName.compare("clear") == 0){ |
486 | cfg.writeEntry("Apps", ""); | 486 | cfg.writeEntry("Apps", ""); |
487 | } | 487 | } |
488 | } else if ( msg == "autoStart(QString,QString)" ) { | 488 | } else if ( msg == "autoStart(QString,QString)" ) { |
489 | QString modifier, appName; | 489 | QString modifier, appName; |
490 | stream >> modifier >> appName; | 490 | stream >> modifier >> appName; |
491 | Config cfg( "autostart" ); | 491 | Config cfg( "autostart" ); |
492 | cfg.setGroup( "AutoStart" ); | 492 | cfg.setGroup( "AutoStart" ); |
493 | if ( modifier.compare("add") == 0 ){ | 493 | if ( modifier.compare("add") == 0 ){ |
494 | // only add if appname is entered | 494 | // only add if appname is entered |
495 | if (!appName.isEmpty()) { | 495 | if (!appName.isEmpty()) { |
496 | cfg.writeEntry("Apps", appName); | 496 | cfg.writeEntry("Apps", appName); |
497 | } | 497 | } |
498 | } else if (modifier.compare("remove") == 0 ) { | 498 | } else if (modifier.compare("remove") == 0 ) { |
499 | // need to change for multiple entries | 499 | // need to change for multiple entries |
500 | // actually remove is right now simular to clear, but in future there | 500 | // actually remove is right now simular to clear, but in future there |
501 | // should be multiple apps in autostart possible. | 501 | // should be multiple apps in autostart possible. |
502 | QString checkName; | 502 | QString checkName; |
503 | checkName = cfg.readEntry("Apps", ""); | 503 | checkName = cfg.readEntry("Apps", ""); |
504 | if (checkName == appName) { | 504 | if (checkName == appName) { |
505 | cfg.writeEntry("Apps", ""); | 505 | cfg.writeEntry("Apps", ""); |
506 | } | 506 | } |
507 | } | 507 | } |
508 | // case the autostart feature should be delayed | 508 | // case the autostart feature should be delayed |
509 | } else if ( msg == "autoStart(QString,QString,QString)") { | 509 | } else if ( msg == "autoStart(QString,QString,QString)") { |
510 | QString modifier, appName, delay; | 510 | QString modifier, appName, delay; |
511 | stream >> modifier >> appName >> delay; | 511 | stream >> modifier >> appName >> delay; |
512 | Config cfg( "autostart" ); | 512 | Config cfg( "autostart" ); |
513 | 513 | ||
514 | cfg.setGroup( "AutoStart" ); | 514 | cfg.setGroup( "AutoStart" ); |
515 | if ( modifier.compare("add") == 0 ){ | 515 | if ( modifier.compare("add") == 0 ){ |
516 | // only add it appname is entered | 516 | // only add it appname is entered |
517 | if (!appName.isEmpty()) { | 517 | if (!appName.isEmpty()) { |
518 | cfg.writeEntry("Apps", appName); | 518 | cfg.writeEntry("Apps", appName); |
519 | cfg.writeEntry("Delay", delay); | 519 | cfg.writeEntry("Delay", delay); |
520 | } | 520 | } |
521 | } else { | 521 | } else { |
522 | } | 522 | } |
523 | } | 523 | } |
524 | #endif | 524 | #endif |
525 | } | 525 | } |
526 | 526 | ||
527 | void Server::receiveTaskBar(const QCString &msg, const QByteArray &data) | 527 | void Server::receiveTaskBar(const QCString &msg, const QByteArray &data) |
528 | { | 528 | { |
529 | QDataStream stream( data, IO_ReadOnly ); | 529 | QDataStream stream( data, IO_ReadOnly ); |
530 | 530 | ||
531 | if ( msg == "reloadApps()" ) { | 531 | if ( msg == "reloadApps()" ) { |
532 | docList->reloadAppLnks(); | 532 | docList->reloadAppLnks(); |
533 | } else if ( msg == "soundAlarm()" ) { | 533 | } else if ( msg == "soundAlarm()" ) { |
534 | ServerApplication::soundAlarm(); | 534 | ServerApplication::soundAlarm(); |
535 | } | 535 | } |
536 | else if ( msg == "setLed(int,bool)" ) { | 536 | else if ( msg == "setLed(int,bool)" ) { |
537 | int led, status; | 537 | int led, status; |
538 | stream >> led >> status; | 538 | stream >> led >> status; |
539 | 539 | ||
540 | QValueList <OLed> ll = ODevice::inst ( )-> ledList ( ); | 540 | QValueList <OLed> ll = ODevice::inst ( )-> ledList ( ); |
541 | if ( ll. count ( )){ | 541 | if ( ll. count ( )) { |
542 | OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0]; | 542 | OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0]; |
543 | bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow ); | 543 | bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow ); |
544 | 544 | ||
545 | ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off ); | 545 | ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off ); |
546 | } | 546 | } |
547 | } | 547 | } |
548 | } | 548 | } |
549 | 549 | ||
550 | void Server::cancelSync() | 550 | void Server::cancelSync() |
551 | { | 551 | { |
552 | #ifndef QT_NO_COP | 552 | #ifndef QT_NO_COP |
553 | QCopEnvelope e( "QPE/Desktop", "cancelSync()" ); | 553 | QCopEnvelope e( "QPE/Desktop", "cancelSync()" ); |
554 | #endif | 554 | #endif |
555 | delete syncDialog; | 555 | delete syncDialog; |
556 | syncDialog = 0; | 556 | syncDialog = 0; |
557 | } | 557 | } |
558 | 558 | ||
559 | bool Server::mkdir(const QString &localPath) | 559 | bool Server::mkdir(const QString &localPath) |
560 | { | 560 | { |
561 | QDir fullDir(localPath); | 561 | QDir fullDir(localPath); |
562 | if (fullDir.exists()) | 562 | if (fullDir.exists()) |
563 | return true; | 563 | return true; |
564 | 564 | ||
565 | // at this point the directory doesn't exist | 565 | // at this point the directory doesn't exist |
566 | // go through the directory tree and start creating the direcotories | 566 | // go through the directory tree and start creating the direcotories |
567 | // that don't exist; if we can't create the directories, return false | 567 | // that don't exist; if we can't create the directories, return false |
568 | 568 | ||
569 | QString dirSeps = "/"; | 569 | QString dirSeps = "/"; |
570 | int dirIndex = localPath.find(dirSeps); | 570 | int dirIndex = localPath.find(dirSeps); |
571 | QString checkedPath; | 571 | QString checkedPath; |
572 | 572 | ||
573 | // didn't find any seps; weird, use the cur dir instead | 573 | // didn't find any seps; weird, use the cur dir instead |
574 | if (dirIndex == -1) { | 574 | if (dirIndex == -1) { |
575 | //odebug << "No seperators found in path " << localPath << "" << oendl; | 575 | //odebug << "No seperators found in path " << localPath << "" << oendl; |
576 | checkedPath = QDir::currentDirPath(); | 576 | checkedPath = QDir::currentDirPath(); |
577 | } | 577 | } |
578 | 578 | ||
579 | while (checkedPath != localPath) { | 579 | while (checkedPath != localPath) { |
580 | // no more seperators found, use the local path | 580 | // no more seperators found, use the local path |
581 | if (dirIndex == -1) | 581 | if (dirIndex == -1) |
582 | checkedPath = localPath; | 582 | checkedPath = localPath; |
583 | else { | 583 | else { |
584 | // the next directory to check | 584 | // the next directory to check |
585 | checkedPath = localPath.left(dirIndex) + "/"; | 585 | checkedPath = localPath.left(dirIndex) + "/"; |
586 | // advance the iterator; the next dir seperator | 586 | // advance the iterator; the next dir seperator |
587 | dirIndex = localPath.find(dirSeps, dirIndex+1); | 587 | dirIndex = localPath.find(dirSeps, dirIndex+1); |
588 | } | 588 | } |
589 | 589 | ||
590 | QDir checkDir(checkedPath); | 590 | QDir checkDir(checkedPath); |
591 | if (!checkDir.exists()) { | 591 | if (!checkDir.exists()) { |
592 | //odebug << "mkdir making dir " << checkedPath << "" << oendl; | 592 | //odebug << "mkdir making dir " << checkedPath << "" << oendl; |
593 | 593 | ||
594 | if (!checkDir.mkdir(checkedPath)) { | 594 | if (!checkDir.mkdir(checkedPath)) { |
595 | odebug << "Unable to make directory " << checkedPath << "" << oendl; | 595 | odebug << "Unable to make directory " << checkedPath << "" << oendl; |
596 | return FALSE; | 596 | return FALSE; |
597 | } | 597 | } |
598 | } | 598 | } |
599 | 599 | ||
600 | } | 600 | } |
601 | return TRUE; | 601 | return TRUE; |
602 | } | 602 | } |
603 | 603 | ||
604 | void Server::styleChange( QStyle &s ) | 604 | void Server::styleChange( QStyle &s ) |
605 | { | 605 | { |
606 | QWidget::styleChange( s ); | 606 | QWidget::styleChange( s ); |
607 | } | 607 | } |
608 | 608 | ||
609 | void Server::startTransferServer() | 609 | void Server::startTransferServer() |
610 | { | 610 | { |
611 | if ( !qcopBridge ) { | 611 | if ( !qcopBridge ) { |
612 | // start qcop bridge server | 612 | // start qcop bridge server |
613 | qcopBridge = new QCopBridge( 4243 ); | 613 | qcopBridge = new QCopBridge( 4243 ); |
614 | if ( qcopBridge->ok() ) { | 614 | if ( qcopBridge->ok() ) { |
615 | // ... OK | 615 | // ... OK |
616 | connect( qcopBridge, SIGNAL(connectionClosed(const QHostAddress&)), | 616 | connect( qcopBridge, SIGNAL(connectionClosed(const QHostAddress&)), |
617 | this, SLOT(syncConnectionClosed(const QHostAddress&)) ); | 617 | this, SLOT(syncConnectionClosed(const QHostAddress&)) ); |
618 | } else { | 618 | } else { |
619 | delete qcopBridge; | 619 | delete qcopBridge; |
620 | qcopBridge = 0; | 620 | qcopBridge = 0; |
621 | } | 621 | } |
622 | } | 622 | } |
623 | if ( !transferServer ) { | 623 | if ( !transferServer ) { |
624 | // start transfer server | 624 | // start transfer server |
625 | transferServer = new TransferServer( 4242 ); | 625 | transferServer = new TransferServer( 4242 ); |
626 | if ( transferServer->ok() ) { | 626 | if ( transferServer->ok() ) { |
627 | // ... OK | 627 | // ... OK |
628 | } else { | 628 | } else { |
629 | delete transferServer; | 629 | delete transferServer; |
630 | transferServer = 0; | 630 | transferServer = 0; |
631 | } | 631 | } |
632 | } | 632 | } |
633 | if ( !transferServer || !qcopBridge ) | 633 | if ( !transferServer || !qcopBridge ) |
634 | tid_xfer = startTimer( 2000 ); | 634 | tid_xfer = startTimer( 2000 ); |
635 | } | 635 | } |
636 | 636 | ||
637 | void Server::timerEvent( QTimerEvent *e ) | 637 | void Server::timerEvent( QTimerEvent *e ) |
638 | { | 638 | { |
639 | if ( e->timerId() == tid_xfer ) { | 639 | if ( e->timerId() == tid_xfer ) { |
640 | killTimer( tid_xfer ); | 640 | killTimer( tid_xfer ); |
641 | tid_xfer = 0; | 641 | tid_xfer = 0; |
642 | startTransferServer(); | 642 | startTransferServer(); |
643 | } | 643 | } |
644 | /* ### FIXME today startin */ | 644 | /* ### FIXME today startin */ |
645 | #if 0 | 645 | #if 0 |
646 | else if ( e->timerId() == tid_today ) { | 646 | else if ( e->timerId() == tid_today ) { |
647 | QDate today = QDate::currentDate(); | 647 | QDate today = QDate::currentDate(); |
648 | if ( today != last_today_show ) { | 648 | if ( today != last_today_show ) { |
649 | last_today_show = today; | 649 | last_today_show = today; |
650 | Config cfg("today"); | 650 | Config cfg("today"); |
651 | cfg.setGroup("Start"); | 651 | cfg.setGroup("Start"); |
652 | #ifndef QPE_DEFAULT_TODAY_MODE | 652 | #ifndef QPE_DEFAULT_TODAY_MODE |
653 | #define QPE_DEFAULT_TODAY_MODE "Never" | 653 | #define QPE_DEFAULT_TODAY_MODE "Never" |
654 | #endif | 654 | #endif |
655 | if ( cfg.readEntry("Mode",QPE_DEFAULT_TODAY_MODE) == "Daily" ) { | 655 | if ( cfg.readEntry("Mode",QPE_DEFAULT_TODAY_MODE) == "Daily" ) { |
656 | QCopEnvelope env(Service::channel("today"),"raise()"); | 656 | QCopEnvelope env(Service::channel("today"),"raise()"); |
657 | } | 657 | } |
658 | } | 658 | } |
659 | } | 659 | } |
660 | #endif | 660 | #endif |
661 | } | 661 | } |
662 | 662 | ||
663 | void Server::terminateServers() | 663 | void Server::terminateServers() |
664 | { | 664 | { |
665 | delete transferServer; | 665 | delete transferServer; |
666 | delete qcopBridge; | 666 | delete qcopBridge; |
667 | transferServer = 0; | 667 | transferServer = 0; |
668 | qcopBridge = 0; | 668 | qcopBridge = 0; |
669 | } | 669 | } |
670 | 670 | ||
671 | void Server::syncConnectionClosed( const QHostAddress & ) | 671 | void Server::syncConnectionClosed( const QHostAddress & ) |
672 | { | 672 | { |
673 | odebug << "Lost sync connection" << oendl; | 673 | odebug << "Lost sync connection" << oendl; |
674 | delete syncDialog; | 674 | delete syncDialog; |
675 | syncDialog = 0; | 675 | syncDialog = 0; |
676 | } | 676 | } |
677 | 677 | ||
678 | void Server::pokeTimeMonitors() | 678 | void Server::pokeTimeMonitors() |
679 | { | 679 | { |
680 | #if 0 | 680 | #if 0 |
681 | // inform all TimeMonitors | 681 | // inform all TimeMonitors |
682 | QStrList tms = Service::channels("TimeMonitor"); | 682 | QStrList tms = Service::channels("TimeMonitor"); |
683 | for (const char* ch = tms.first(); ch; ch=tms.next()) { | 683 | for (const char* ch = tms.first(); ch; ch=tms.next()) { |
684 | QString t = getenv("TZ"); | 684 | QString t = getenv("TZ"); |
685 | QCopEnvelope e(ch, "timeChange(QString)"); | 685 | QCopEnvelope e(ch, "timeChange(QString)"); |
686 | e << t; | 686 | e << t; |
687 | } | 687 | } |
688 | #endif | 688 | #endif |
689 | } | 689 | } |
690 | 690 | ||
691 | void Server::applicationLaunched(int, const QString &app) | 691 | void Server::applicationLaunched(int, const QString &app) |
692 | { | 692 | { |
693 | serverGui->applicationStateChanged( app, ServerInterface::Launching ); | 693 | serverGui->applicationStateChanged( app, ServerInterface::Launching ); |
694 | } | 694 | } |
695 | 695 | ||
696 | void Server::applicationTerminated(int pid, const QString &app) | 696 | void Server::applicationTerminated(int pid, const QString &app) |
697 | { | 697 | { |
698 | serverGui->applicationStateChanged( app, ServerInterface::Terminated ); | 698 | serverGui->applicationStateChanged( app, ServerInterface::Terminated ); |
699 | #if 0 | 699 | #if 0 |
700 | tsmMonitor->applicationTerminated( pid ); | 700 | tsmMonitor->applicationTerminated( pid ); |
701 | #endif | 701 | #endif |
702 | } | 702 | } |
703 | 703 | ||
704 | void Server::applicationConnected(const QString &app) | 704 | void Server::applicationConnected(const QString &app) |
705 | { | 705 | { |
706 | serverGui->applicationStateChanged( app, ServerInterface::Running ); | 706 | serverGui->applicationStateChanged( app, ServerInterface::Running ); |
707 | } | 707 | } |
708 | 708 | ||
709 | void Server::storageChanged() | 709 | void Server::storageChanged() |
710 | { | 710 | { |
711 | system( "opie-update-symlinks" ); | 711 | system( "opie-update-symlinks" ); |
712 | serverGui->storageChanged( storage->fileSystems() ); | 712 | serverGui->storageChanged( storage->fileSystems() ); |
713 | docList->storageChanged(); | 713 | docList->storageChanged(); |
714 | } | 714 | } |
715 | 715 | ||
716 | 716 | ||
717 | 717 | ||
718 | void Server::preloadApps() | 718 | void Server::preloadApps() |
719 | { | 719 | { |
720 | Config cfg("Launcher"); | 720 | Config cfg("Launcher"); |
721 | cfg.setGroup("Preload"); | 721 | cfg.setGroup("Preload"); |
722 | QStringList apps = cfg.readListEntry("Apps",','); | 722 | QStringList apps = cfg.readListEntry("Apps",','); |
723 | for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) { | 723 | for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) { |
724 | #ifndef QT_NO_COP | 724 | #ifndef QT_NO_COP |
725 | QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()"); | 725 | QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()"); |
726 | #endif | 726 | #endif |
727 | } | 727 | } |
728 | } | 728 | } |
729 | 729 | ||
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp index 4b764e3..c3f936e 100644 --- a/core/launcher/transferserver.cpp +++ b/core/launcher/transferserver.cpp | |||
@@ -17,1415 +17,1414 @@ | |||
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | #include "transferserver.h" | 20 | #include "transferserver.h" |
21 | 21 | ||
22 | /* OPIE */ | 22 | /* OPIE */ |
23 | #include <opie2/odebug.h> | 23 | #include <opie2/odebug.h> |
24 | #include <opie2/oglobal.h> | 24 | #include <opie2/oglobal.h> |
25 | #include <qtopia/qprocess.h> | 25 | #include <qtopia/qprocess.h> |
26 | #include <qtopia/process.h> | 26 | #include <qtopia/process.h> |
27 | #include <qtopia/private/contact.h> | 27 | #include <qtopia/private/contact.h> |
28 | #include <qtopia/version.h> | 28 | #include <qtopia/version.h> |
29 | #ifdef Q_WS_QWS | 29 | #ifdef Q_WS_QWS |
30 | #include <qtopia/qcopenvelope_qws.h> | 30 | #include <qtopia/qcopenvelope_qws.h> |
31 | #endif | 31 | #endif |
32 | using namespace Opie::Core; | 32 | using namespace Opie::Core; |
33 | 33 | ||
34 | /* QT */ | 34 | /* QT */ |
35 | #include <qtextstream.h> | 35 | #include <qtextstream.h> |
36 | #include <qmessagebox.h> | 36 | #include <qmessagebox.h> |
37 | 37 | ||
38 | /* STD */ | 38 | /* STD */ |
39 | #include <pwd.h> | 39 | #include <pwd.h> |
40 | #include <sys/types.h> | 40 | #include <sys/types.h> |
41 | #include <unistd.h> | 41 | #include <unistd.h> |
42 | #include <stdlib.h> | 42 | #include <stdlib.h> |
43 | #include <time.h> | 43 | #include <time.h> |
44 | 44 | ||
45 | #ifndef Q_OS_MACX | 45 | #ifndef Q_OS_MACX |
46 | #include <shadow.h> | 46 | #include <shadow.h> |
47 | #include <crypt.h> | 47 | #include <crypt.h> |
48 | #endif /* Q_OS_MACX */ | 48 | #endif /* Q_OS_MACX */ |
49 | 49 | ||
50 | const int block_size = 51200; | 50 | const int block_size = 51200; |
51 | 51 | ||
52 | TransferServer::TransferServer( Q_UINT16 port, QObject *parent, | 52 | TransferServer::TransferServer( Q_UINT16 port, QObject *parent, |
53 | const char* name) | 53 | const char* name) |
54 | : QServerSocket( port, 1, parent, name ) | 54 | : QServerSocket( port, 1, parent, name ) |
55 | { | 55 | { |
56 | connections.setAutoDelete( TRUE ); | 56 | connections.setAutoDelete( TRUE ); |
57 | if ( !ok() ) | 57 | if ( !ok() ) |
58 | owarn << "Failed to bind to port " << port << "" << oendl; | 58 | owarn << "Failed to bind to port " << port << "" << oendl; |
59 | } | 59 | } |
60 | 60 | ||
61 | void TransferServer::authorizeConnections() | 61 | void TransferServer::authorizeConnections() |
62 | { | 62 | { |
63 | QListIterator<ServerPI> it(connections); | 63 | QListIterator<ServerPI> it(connections); |
64 | while ( it.current() ) { | 64 | while ( it.current() ) { |
65 | if ( !it.current()->verifyAuthorised() ) { | 65 | if ( !it.current()->verifyAuthorised() ) { |
66 | disconnect( it.current(), SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); | 66 | disconnect( it.current(), SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); |
67 | connections.removeRef( it.current() ); | 67 | connections.removeRef( it.current() ); |
68 | } else | 68 | } else |
69 | ++it; | 69 | ++it; |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | void TransferServer::closed(ServerPI *item) | 73 | void TransferServer::closed(ServerPI *item) |
74 | { | 74 | { |
75 | connections.removeRef(item); | 75 | connections.removeRef(item); |
76 | } | 76 | } |
77 | 77 | ||
78 | TransferServer::~TransferServer() | 78 | TransferServer::~TransferServer() |
79 | { | 79 | { |
80 | } | 80 | } |
81 | 81 | ||
82 | void TransferServer::newConnection( int socket ) | 82 | void TransferServer::newConnection( int socket ) |
83 | { | 83 | { |
84 | ServerPI *ptr = new ServerPI( socket, this ); | 84 | ServerPI *ptr = new ServerPI( socket, this ); |
85 | connect( ptr, SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); | 85 | connect( ptr, SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); |
86 | connections.append( ptr ); | 86 | connections.append( ptr ); |
87 | } | 87 | } |
88 | 88 | ||
89 | QString SyncAuthentication::serverId() | 89 | QString SyncAuthentication::serverId() |
90 | { | 90 | { |
91 | Config cfg("Security"); | 91 | Config cfg("Security"); |
92 | cfg.setGroup("Sync"); | 92 | cfg.setGroup("Sync"); |
93 | QString r = cfg.readEntry("serverid"); | 93 | QString r = cfg.readEntry("serverid"); |
94 | 94 | ||
95 | if ( r.isEmpty() ) { | 95 | if ( r.isEmpty() ) { |
96 | r = OGlobal::generateUuid(); | 96 | r = OGlobal::generateUuid(); |
97 | cfg.writeEntry("serverid", r ); | 97 | cfg.writeEntry("serverid", r ); |
98 | } | 98 | } |
99 | return r; | 99 | return r; |
100 | } | 100 | } |
101 | 101 | ||
102 | QString SyncAuthentication::ownerName() | 102 | QString SyncAuthentication::ownerName() |
103 | { | 103 | { |
104 | QString vfilename = Global::applicationFileName("addressbook", | 104 | QString vfilename = Global::applicationFileName("addressbook", |
105 | "businesscard.vcf"); | 105 | "businesscard.vcf"); |
106 | if (QFile::exists(vfilename)) { | 106 | if (QFile::exists(vfilename)) { |
107 | Contact c; | 107 | Contact c; |
108 | c = Contact::readVCard( vfilename )[0]; | 108 | c = Contact::readVCard( vfilename )[0]; |
109 | return c.fullName(); | 109 | return c.fullName(); |
110 | } | 110 | } |
111 | 111 | ||
112 | return QString::null; | 112 | return QString::null; |
113 | } | 113 | } |
114 | 114 | ||
115 | QString SyncAuthentication::loginName() | 115 | QString SyncAuthentication::loginName() |
116 | { | 116 | { |
117 | struct passwd *pw = 0L; | 117 | struct passwd *pw = 0L; |
118 | #ifndef Q_OS_WIN32 | 118 | #ifndef Q_OS_WIN32 |
119 | pw = getpwuid( geteuid() ); | 119 | pw = getpwuid( geteuid() ); |
120 | return QString::fromLocal8Bit( pw->pw_name ); | 120 | return QString::fromLocal8Bit( pw->pw_name ); |
121 | #else | 121 | #else |
122 | //### revise | 122 | //### revise |
123 | return QString(); | 123 | return QString(); |
124 | #endif | 124 | #endif |
125 | } | 125 | } |
126 | 126 | ||
127 | int SyncAuthentication::isAuthorized(QHostAddress peeraddress) | 127 | int SyncAuthentication::isAuthorized(QHostAddress peeraddress) |
128 | { | 128 | { |
129 | Config cfg("Security"); | 129 | Config cfg("Security"); |
130 | cfg.setGroup("Sync"); | 130 | cfg.setGroup("Sync"); |
131 | // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); | 131 | // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); |
132 | uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100); | 132 | uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100); |
133 | 133 | ||
134 | // QHostAddress allowed; | 134 | // QHostAddress allowed; |
135 | // allowed.setAddress(allowedstr); | 135 | // allowed.setAddress(allowedstr); |
136 | // uint auth_peer = allowed.ip4Addr(); | 136 | // uint auth_peer = allowed.ip4Addr(); |
137 | uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24); | 137 | uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24); |
138 | uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined | 138 | uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined |
139 | ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits)); | 139 | ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits)); |
140 | 140 | ||
141 | return (peeraddress.ip4Addr() & mask) == auth_peer; | 141 | return (peeraddress.ip4Addr() & mask) == auth_peer; |
142 | } | 142 | } |
143 | 143 | ||
144 | bool SyncAuthentication::checkUser( const QString& user ) | 144 | bool SyncAuthentication::checkUser( const QString& user ) |
145 | { | 145 | { |
146 | if ( user.isEmpty() ) return FALSE; | 146 | if ( user.isEmpty() ) return FALSE; |
147 | QString euser = loginName(); | 147 | QString euser = loginName(); |
148 | return user == euser; | 148 | return user == euser; |
149 | } | 149 | } |
150 | 150 | ||
151 | bool SyncAuthentication::checkPassword( const QString& password ) | 151 | bool SyncAuthentication::checkPassword( const QString& password ) |
152 | { | 152 | { |
153 | #ifdef ALLOW_UNIX_USER_FTP | 153 | #ifdef ALLOW_UNIX_USER_FTP |
154 | // First, check system password... | 154 | // First, check system password... |
155 | 155 | ||
156 | struct passwd *pw = 0; | 156 | struct passwd *pw = 0; |
157 | struct spwd *spw = 0; | 157 | struct spwd *spw = 0; |
158 | 158 | ||
159 | pw = getpwuid( geteuid() ); | 159 | pw = getpwuid( geteuid() ); |
160 | spw = getspnam( pw->pw_name ); | 160 | spw = getspnam( pw->pw_name ); |
161 | 161 | ||
162 | QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); | 162 | QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); |
163 | if ( cpwd == "x" && spw ) | 163 | if ( cpwd == "x" && spw ) |
164 | cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); | 164 | cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); |
165 | 165 | ||
166 | // Note: some systems use more than crypt for passwords. | 166 | // Note: some systems use more than crypt for passwords. |
167 | QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); | 167 | QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); |
168 | if ( cpwd == cpassword ) | 168 | if ( cpwd == cpassword ) |
169 | return TRUE; | 169 | return TRUE; |
170 | #endif | 170 | #endif |
171 | 171 | ||
172 | static int lastdenial=0; | 172 | static int lastdenial=0; |
173 | static int denials=0; | 173 | static int denials=0; |
174 | int now = time(0); | 174 | int now = time(0); |
175 | 175 | ||
176 | Config cfg("Security"); | 176 | Config cfg("Security"); |
177 | cfg.setGroup("SyncMode"); | 177 | cfg.setGroup("SyncMode"); |
178 | int mode = cfg.readNumEntry("Mode", 0x02 ); | 178 | int mode = cfg.readNumEntry("Mode", 0x02 ); |
179 | 179 | ||
180 | //No pass word needed if the user really needs it | 180 | //No pass word needed if the user really needs it |
181 | if (mode & 0x04) { | 181 | if (mode & 0x04) { |
182 | QMessageBox unauth( | 182 | QMessageBox unauth( |
183 | tr("Sync Connection"), | 183 | tr("Sync Connection"), |
184 | tr("<qt><p>An unauthorized system is requesting access to this device." | 184 | tr("<qt><p>An unauthorized system is requesting access to this device." |
185 | "<p>You chose IntelliSync so you may I allow or deny this connection.</qt>" ), | 185 | "<p>You chose IntelliSync so you may I allow or deny this connection.</qt>" ), |
186 | QMessageBox::Warning, | 186 | QMessageBox::Warning, |
187 | QMessageBox::Ok, QMessageBox::Cancel|QMessageBox::Default, QMessageBox::NoButton, | 187 | QMessageBox::Ok, QMessageBox::Cancel|QMessageBox::Default, QMessageBox::NoButton, |
188 | 0, QString::null, TRUE, WStyle_StaysOnTop); | 188 | 0, QString::null, TRUE, WStyle_StaysOnTop); |
189 | unauth.setButtonText(QMessageBox::Ok, tr("Allow" ) ); | 189 | unauth.setButtonText(QMessageBox::Ok, tr("Allow" ) ); |
190 | unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); | 190 | unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); |
191 | switch( unauth.exec() ) { | 191 | switch( unauth.exec() ) { |
192 | case QMessageBox::Ok: | 192 | case QMessageBox::Ok: |
193 | return TRUE; | 193 | return TRUE; |
194 | break; | 194 | break; |
195 | case QMessageBox::Cancel: | 195 | case QMessageBox::Cancel: |
196 | default: | 196 | default: |
197 | denials++; | 197 | denials++; |
198 | lastdenial=now; | 198 | lastdenial=now; |
199 | return FALSE; | 199 | return FALSE; |
200 | } | 200 | } |
201 | } | 201 | } |
202 | 202 | ||
203 | // Detect old Qtopia Desktop (no password) and fail | 203 | // Detect old Qtopia Desktop (no password) and fail |
204 | if ( password.isEmpty() ) { | 204 | if ( password.isEmpty() ) { |
205 | if ( denials < 3 || now > lastdenial+600 ) { | 205 | if ( denials < 3 || now > lastdenial+600 ) { |
206 | QMessageBox unauth( | 206 | QMessageBox unauth( |
207 | tr("Sync Connection"), | 207 | tr("Sync Connection"), |
208 | tr("<p>An unauthorized system is requesting access to this device." | 208 | tr("<p>An unauthorized system is requesting access to this device." |
209 | "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " | 209 | "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " |
210 | "please upgrade or change the security setting to use IntelliSync." ), | 210 | "please upgrade or change the security setting to use IntelliSync." ), |
211 | QMessageBox::Warning, | 211 | QMessageBox::Warning, |
212 | QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton, | 212 | QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton, |
213 | 0, QString::null, TRUE, WStyle_StaysOnTop); | 213 | 0, QString::null, TRUE, WStyle_StaysOnTop); |
214 | unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); | 214 | unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); |
215 | unauth.exec(); | 215 | unauth.exec(); |
216 | 216 | ||
217 | denials++; | 217 | denials++; |
218 | lastdenial=now; | 218 | lastdenial=now; |
219 | } | 219 | } |
220 | return FALSE; | 220 | return FALSE; |
221 | 221 | ||
222 | } | 222 | } |
223 | 223 | ||
224 | // Second, check sync password... | 224 | // Second, check sync password... |
225 | 225 | ||
226 | static int lock=0; | 226 | static int lock=0; |
227 | if ( lock ) return FALSE; | 227 | if ( lock ) return FALSE; |
228 | 228 | ||
229 | ++lock; | 229 | ++lock; |
230 | 230 | ||
231 | /* | 231 | /* |
232 | * we need to support old Sync software and QtopiaDesktop | 232 | * we need to support old Sync software and QtopiaDesktop |
233 | */ | 233 | */ |
234 | if ( password.left(6) == "Qtopia" || password.left(6) == "rootme" ) { | 234 | if ( password.left(6) == "Qtopia" || password.left(6) == "rootme" ) { |
235 | Config cfg( "Security" ); | 235 | Config cfg( "Security" ); |
236 | cfg.setGroup("Sync"); | 236 | cfg.setGroup("Sync"); |
237 | QStringList pwds = cfg.readListEntry("Passwords",' '); | 237 | QStringList pwds = cfg.readListEntry("Passwords",' '); |
238 | for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) { | 238 | for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) { |
239 | #ifndef Q_OS_WIN32 | 239 | #ifndef Q_OS_WIN32 |
240 | QString cpassword = QString::fromLocal8Bit( | 240 | QString cpassword = QString::fromLocal8Bit( |
241 | crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); | 241 | crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); |
242 | #else | 242 | #else |
243 | // ### revise | 243 | // ### revise |
244 | QString cpassword(""); | 244 | QString cpassword(""); |
245 | #endif | 245 | #endif |
246 | if ( *it == cpassword ) { | 246 | if ( *it == cpassword ) { |
247 | lock--; | 247 | lock--; |
248 | return TRUE; | 248 | return TRUE; |
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
252 | // Unrecognized system. Be careful... | 252 | // Unrecognized system. Be careful... |
253 | QMessageBox unrecbox( | 253 | QMessageBox unrecbox( |
254 | tr("Sync Connection"), | 254 | tr("Sync Connection"), |
255 | tr("<p>An unrecognized system is requesting access to this device." | 255 | tr( "<p>An unrecognized system is requesting access to this device." |
256 | "<p>If you have just initiated a Sync for the first time, this is normal."), | 256 | "<p>If you have just initiated a Sync for the first time, this is normal."), |
257 | QMessageBox::Warning, | 257 | QMessageBox::Warning, |
258 | QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton, | 258 | QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton, |
259 | 0, QString::null, TRUE, WStyle_StaysOnTop); | 259 | 0, QString::null, TRUE, WStyle_StaysOnTop); |
260 | unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny")); | 260 | unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny")); |
261 | unrecbox.setButtonText(QMessageBox::Yes, tr("Allow")); | 261 | unrecbox.setButtonText(QMessageBox::Yes, tr("Allow")); |
262 | 262 | ||
263 | if ( (denials > 2 && now < lastdenial+600) | 263 | if ( (denials > 2 && now < lastdenial+600) |
264 | || unrecbox.exec() != QMessageBox::Yes) | 264 | || unrecbox.exec() != QMessageBox::Yes) |
265 | { | 265 | { |
266 | denials++; | 266 | denials++; |
267 | lastdenial=now; | 267 | lastdenial=now; |
268 | lock--; | 268 | lock--; |
269 | return FALSE; | 269 | return FALSE; |
270 | } else { | 270 | } else { |
271 | const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."; | 271 | const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."; |
272 | char salt[2]; | 272 | char salt[2]; |
273 | salt[0]= salty[rand() % (sizeof(salty)-1)]; | 273 | salt[0]= salty[rand() % (sizeof(salty)-1)]; |
274 | salt[1]= salty[rand() % (sizeof(salty)-1)]; | 274 | salt[1]= salty[rand() % (sizeof(salty)-1)]; |
275 | #ifndef Q_OS_WIN32 | 275 | #ifndef Q_OS_WIN32 |
276 | QString cpassword = QString::fromLocal8Bit( | 276 | QString cpassword = QString::fromLocal8Bit( |
277 | crypt( password.mid(8).local8Bit(), salt ) ); | 277 | crypt( password.mid(8).local8Bit(), salt ) ); |
278 | #else | 278 | #else |
279 | //### revise | 279 | //### revise |
280 | QString cpassword(""); | 280 | QString cpassword(""); |
281 | #endif | 281 | #endif |
282 | denials=0; | 282 | denials=0; |
283 | pwds.prepend(cpassword); | 283 | pwds.prepend(cpassword); |
284 | cfg.writeEntry("Passwords",pwds,' '); | 284 | cfg.writeEntry("Passwords",pwds,' '); |
285 | lock--; | 285 | lock--; |
286 | return TRUE; | 286 | return TRUE; |
287 | } | 287 | } |
288 | } | 288 | } |
289 | lock--; | 289 | lock--; |
290 | 290 | ||
291 | return FALSE; | 291 | return FALSE; |
292 | } | 292 | } |
293 | 293 | ||
294 | 294 | ||
295 | ServerPI::ServerPI( int socket, QObject *parent, const char* name ) | 295 | ServerPI::ServerPI( int socket, QObject *parent, const char* name ) |
296 | : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ), | 296 | : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ), |
297 | storFileSize(-1) | 297 | storFileSize(-1) |
298 | { | 298 | { |
299 | state = Connected; | 299 | state = Connected; |
300 | 300 | ||
301 | setSocket( socket ); | 301 | setSocket( socket ); |
302 | 302 | ||
303 | peerport = peerPort(); | 303 | peerport = peerPort(); |
304 | peeraddress = peerAddress(); | 304 | peeraddress = peerAddress(); |
305 | 305 | ||
306 | #ifndef INSECURE | 306 | #ifndef INSECURE |
307 | if ( !SyncAuthentication::isAuthorized(peeraddress) ) { | 307 | if ( !SyncAuthentication::isAuthorized(peeraddress) ) { |
308 | state = Forbidden; | 308 | state = Forbidden; |
309 | startTimer( 0 ); | 309 | startTimer( 0 ); |
310 | } else | 310 | } else |
311 | #endif | 311 | #endif |
312 | { | 312 | { |
313 | connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); | 313 | connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); |
314 | connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); | 314 | connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); |
315 | 315 | ||
316 | passiv = FALSE; | 316 | passiv = FALSE; |
317 | for( int i = 0; i < 4; i++ ) | 317 | for( int i = 0; i < 4; i++ ) |
318 | wait[i] = FALSE; | 318 | wait[i] = FALSE; |
319 | 319 | ||
320 | send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr | 320 | send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr |
321 | state = Wait_USER; | 321 | state = Wait_USER; |
322 | 322 | ||
323 | dtp = new ServerDTP( this ); | 323 | dtp = new ServerDTP( this ); |
324 | connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); | 324 | connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); |
325 | connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); | 325 | connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); |
326 | connect( dtp, SIGNAL( error(int) ), SLOT( dtpError(int) ) ); | 326 | connect( dtp, SIGNAL( error(int) ), SLOT( dtpError(int) ) ); |
327 | 327 | ||
328 | 328 | ||
329 | directory = QDir::currentDirPath(); | 329 | directory = QDir::currentDirPath(); |
330 | 330 | ||
331 | static int p = 1024; | 331 | static int p = 1024; |
332 | 332 | ||
333 | while ( !serversocket || !serversocket->ok() ) { | 333 | while ( !serversocket || !serversocket->ok() ) { |
334 | delete serversocket; | 334 | delete serversocket; |
335 | serversocket = new ServerSocket( ++p, this ); | 335 | serversocket = new ServerSocket( ++p, this ); |
336 | } | 336 | } |
337 | connect( serversocket, SIGNAL( newIncomming(int) ), | 337 | connect( serversocket, SIGNAL( newIncomming(int) ), |
338 | SLOT( newConnection(int) ) ); | 338 | SLOT( newConnection(int) ) ); |
339 | } | 339 | } |
340 | } | 340 | } |
341 | 341 | ||
342 | ServerPI::~ServerPI() | 342 | ServerPI::~ServerPI() |
343 | { | 343 | { |
344 | close(); | 344 | close(); |
345 | 345 | ||
346 | if ( dtp ) | 346 | if ( dtp ) |
347 | dtp->close(); | 347 | dtp->close(); |
348 | delete dtp; | 348 | delete dtp; |
349 | delete serversocket; | 349 | delete serversocket; |
350 | } | 350 | } |
351 | 351 | ||
352 | bool ServerPI::verifyAuthorised() | 352 | bool ServerPI::verifyAuthorised() |
353 | { | 353 | { |
354 | if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { | 354 | if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { |
355 | state = Forbidden; | 355 | state = Forbidden; |
356 | return FALSE; | 356 | return FALSE; |
357 | } | 357 | } |
358 | return TRUE; | 358 | return TRUE; |
359 | } | 359 | } |
360 | 360 | ||
361 | void ServerPI::connectionClosed() | 361 | void ServerPI::connectionClosed() |
362 | { | 362 | { |
363 | // odebug << "Debug: Connection closed" << oendl; | 363 | // odebug << "Debug: Connection closed" << oendl; |
364 | emit connectionClosed(this); | 364 | emit connectionClosed(this); |
365 | } | 365 | } |
366 | 366 | ||
367 | void ServerPI::send( const QString& msg ) | 367 | void ServerPI::send( const QString& msg ) |
368 | { | 368 | { |
369 | QTextStream os( this ); | 369 | QTextStream os( this ); |
370 | os << msg << endl; | 370 | os << msg << endl; |
371 | //odebug << "Reply: " << msg << "" << oendl; | 371 | //odebug << "Reply: " << msg << "" << oendl; |
372 | } | 372 | } |
373 | 373 | ||
374 | void ServerPI::read() | 374 | void ServerPI::read() |
375 | { | 375 | { |
376 | while ( canReadLine() ) | 376 | while ( canReadLine() ) |
377 | process( readLine().stripWhiteSpace() ); | 377 | process( readLine().stripWhiteSpace() ); |
378 | } | 378 | } |
379 | 379 | ||
380 | bool ServerPI::checkReadFile( const QString& file ) | 380 | bool ServerPI::checkReadFile( const QString& file ) |
381 | { | 381 | { |
382 | QString filename; | 382 | QString filename; |
383 | 383 | ||
384 | if ( file[0] != "/" ) | 384 | if ( file[0] != "/" ) |
385 | filename = directory.path() + "/" + file; | 385 | filename = directory.path() + "/" + file; |
386 | else | 386 | else |
387 | filename = file; | 387 | filename = file; |
388 | 388 | ||
389 | QFileInfo fi( filename ); | 389 | QFileInfo fi( filename ); |
390 | return ( fi.exists() && fi.isReadable() ); | 390 | return ( fi.exists() && fi.isReadable() ); |
391 | } | 391 | } |
392 | 392 | ||
393 | bool ServerPI::checkWriteFile( const QString& file ) | 393 | bool ServerPI::checkWriteFile( const QString& file ) |
394 | { | 394 | { |
395 | QString filename; | 395 | QString filename; |
396 | 396 | ||
397 | if ( file[0] != "/" ) | 397 | if ( file[0] != "/" ) |
398 | filename = directory.path() + "/" + file; | 398 | filename = directory.path() + "/" + file; |
399 | else | 399 | else |
400 | filename = file; | 400 | filename = file; |
401 | 401 | ||
402 | QFileInfo fi( filename ); | 402 | QFileInfo fi( filename ); |
403 | 403 | ||
404 | if ( fi.exists() ) | 404 | if ( fi.exists() ) |
405 | if ( !QFile( filename ).remove() ) | 405 | if ( !QFile( filename ).remove() ) |
406 | return FALSE; | 406 | return FALSE; |
407 | return TRUE; | 407 | return TRUE; |
408 | } | 408 | } |
409 | 409 | ||
410 | void ServerPI::process( const QString& message ) | 410 | void ServerPI::process( const QString& message ) |
411 | { | 411 | { |
412 | //odebug << "Command: " << message << "" << oendl; | 412 | //odebug << "Command: " << message << "" << oendl; |
413 | 413 | ||
414 | // split message using "," as separator | 414 | // split message using "," as separator |
415 | QStringList msg = QStringList::split( " ", message ); | 415 | QStringList msg = QStringList::split( " ", message ); |
416 | if ( msg.isEmpty() ) return; | 416 | if ( msg.isEmpty() ) return; |
417 | 417 | ||
418 | // command token | 418 | // command token |
419 | QString cmd = msg[0].upper(); | 419 | QString cmd = msg[0].upper(); |
420 | 420 | ||
421 | // argument token | 421 | // argument token |
422 | QString arg; | 422 | QString arg; |
423 | if ( msg.count() >= 2 ) | 423 | if ( msg.count() >= 2 ) |
424 | arg = msg[1]; | 424 | arg = msg[1]; |
425 | 425 | ||
426 | // full argument string | 426 | // full argument string |
427 | QString args; | 427 | QString args; |
428 | if ( msg.count() >= 2 ) { | 428 | if ( msg.count() >= 2 ) { |
429 | QStringList copy( msg ); | 429 | QStringList copy( msg ); |
430 | // FIXME: for Qt3 | 430 | // FIXME: for Qt3 |
431 | // copy.pop_front() | 431 | // copy.pop_front() |
432 | copy.remove( copy.begin() ); | 432 | copy.remove( copy.begin() ); |
433 | args = copy.join( " " ); | 433 | args = copy.join( " " ); |
434 | } | 434 | } |
435 | 435 | ||
436 | //odebug << "args: " << args << "" << oendl; | 436 | //odebug << "args: " << args << "" << oendl; |
437 | 437 | ||
438 | // we always respond to QUIT, regardless of state | 438 | // we always respond to QUIT, regardless of state |
439 | if ( cmd == "QUIT" ) { | 439 | if ( cmd == "QUIT" ) { |
440 | send( "211 Good bye!" ); // No tr | 440 | send( "211 Good bye!" ); // No tr |
441 | close(); | 441 | close(); |
442 | return; | 442 | return; |
443 | } | 443 | } |
444 | 444 | ||
445 | // connected to client | 445 | // connected to client |
446 | if ( Connected == state ) | 446 | if ( Connected == state ) |
447 | return; | 447 | return; |
448 | 448 | ||
449 | // waiting for user name | 449 | // waiting for user name |
450 | if ( Wait_USER == state ) { | 450 | if ( Wait_USER == state ) { |
451 | 451 | ||
452 | if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { | 452 | if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { |
453 | send( "530 Please login with USER and PASS" ); // No tr | 453 | send( "530 Please login with USER and PASS" ); // No tr |
454 | return; | 454 | return; |
455 | } | 455 | } |
456 | send( "331 User name ok, need password" ); // No tr | 456 | send( "331 User name ok, need password" ); // No tr |
457 | state = Wait_PASS; | 457 | state = Wait_PASS; |
458 | return; | 458 | return; |
459 | } | 459 | } |
460 | 460 | ||
461 | // waiting for password | 461 | // waiting for password |
462 | if ( Wait_PASS == state ) { | 462 | if ( Wait_PASS == state ) { |
463 | 463 | ||
464 | if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { | 464 | if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { |
465 | send( "530 Please login with USER and PASS" ); // No tr | 465 | send( "530 Please login with USER and PASS" ); // No tr |
466 | return; | 466 | return; |
467 | } | 467 | } |
468 | send( "230 User logged in, proceed" ); // No tr | 468 | send( "230 User logged in, proceed" ); // No tr |
469 | state = Ready; | 469 | state = Ready; |
470 | return; | 470 | return; |
471 | } | 471 | } |
472 | 472 | ||
473 | // ACCESS CONTROL COMMANDS | 473 | // ACCESS CONTROL COMMANDS |
474 | 474 | ||
475 | // Only an ALLO sent immediately before STOR is valid. | 475 | // Only an ALLO sent immediately before STOR is valid. |
476 | if ( cmd != "STOR" ) | 476 | if ( cmd != "STOR" ) |
477 | storFileSize = -1; | 477 | storFileSize = -1; |
478 | 478 | ||
479 | // account (ACCT) | 479 | // account (ACCT) |
480 | if ( cmd == "ACCT" ) { | 480 | if ( cmd == "ACCT" ) { |
481 | // even wu-ftp does not support it | 481 | // even wu-ftp does not support it |
482 | send( "502 Command not implemented" ); // No tr | 482 | send( "502 Command not implemented" ); // No tr |
483 | } | 483 | } |
484 | 484 | ||
485 | // change working directory (CWD) | 485 | // change working directory (CWD) |
486 | else if ( cmd == "CWD" ) { | 486 | else if ( cmd == "CWD" ) { |
487 | 487 | ||
488 | if ( !args.isEmpty() ) { | 488 | if ( !args.isEmpty() ) { |
489 | if ( directory.cd( args, TRUE ) ) | 489 | if ( directory.cd( args, TRUE ) ) |
490 | send( "250 Requested file action okay, completed" ); // No tr | 490 | send( "250 Requested file action okay, completed" ); // No tr |
491 | else | 491 | else |
492 | send( "550 Requested action not taken" ); // No tr | 492 | send( "550 Requested action not taken" ); // No tr |
493 | } | 493 | } |
494 | else | 494 | else |
495 | send( "500 Syntax error, command unrecognized" ); // No tr | 495 | send( "500 Syntax error, command unrecognized" ); // No tr |
496 | } | 496 | } |
497 | 497 | ||
498 | // change to parent directory (CDUP) | 498 | // change to parent directory (CDUP) |
499 | else if ( cmd == "CDUP" ) { | 499 | else if ( cmd == "CDUP" ) { |
500 | if ( directory.cdUp() ) | 500 | if ( directory.cdUp() ) |
501 | send( "250 Requested file action okay, completed" ); // No tr | 501 | send( "250 Requested file action okay, completed" ); // No tr |
502 | else | 502 | else |
503 | send( "550 Requested action not taken" ); // No tr | 503 | send( "550 Requested action not taken" ); // No tr |
504 | } | 504 | } |
505 | 505 | ||
506 | // structure mount (SMNT) | 506 | // structure mount (SMNT) |
507 | else if ( cmd == "SMNT" ) { | 507 | else if ( cmd == "SMNT" ) { |
508 | // even wu-ftp does not support it | 508 | // even wu-ftp does not support it |
509 | send( "502 Command not implemented" ); // No tr | 509 | send( "502 Command not implemented" ); // No tr |
510 | } | 510 | } |
511 | 511 | ||
512 | // reinitialize (REIN) | 512 | // reinitialize (REIN) |
513 | else if ( cmd == "REIN" ) { | 513 | else if ( cmd == "REIN" ) { |
514 | // even wu-ftp does not support it | 514 | // even wu-ftp does not support it |
515 | send( "502 Command not implemented" ); // No tr | 515 | send( "502 Command not implemented" ); // No tr |
516 | } | 516 | } |
517 | 517 | ||
518 | 518 | ||
519 | // TRANSFER PARAMETER COMMANDS | 519 | // TRANSFER PARAMETER COMMANDS |
520 | 520 | ||
521 | 521 | ||
522 | // data port (PORT) | 522 | // data port (PORT) |
523 | else if ( cmd == "PORT" ) { | 523 | else if ( cmd == "PORT" ) { |
524 | if ( parsePort( arg ) ) | 524 | if ( parsePort( arg ) ) |
525 | send( "200 Command okay" ); // No tr | 525 | send( "200 Command okay" ); // No tr |
526 | else | 526 | else |
527 | send( "500 Syntax error, command unrecognized" ); // No tr | 527 | send( "500 Syntax error, command unrecognized" ); // No tr |
528 | } | 528 | } |
529 | 529 | ||
530 | // passive (PASV) | 530 | // passive (PASV) |
531 | else if ( cmd == "PASV" ) { | 531 | else if ( cmd == "PASV" ) { |
532 | passiv = TRUE; | 532 | passiv = TRUE; |
533 | send( "227 Entering Passive Mode (" // No tr | 533 | send( "227 Entering Passive Mode (" // No tr |
534 | + address().toString().replace( QRegExp( "\\." ), "," ) + "," | 534 | + address().toString().replace( QRegExp( "\\." ), "," ) + "," |
535 | + QString::number( ( serversocket->port() ) >> 8 ) + "," | 535 | + QString::number( ( serversocket->port() ) >> 8 ) + "," |
536 | + QString::number( ( serversocket->port() ) & 0xFF ) +")" ); | 536 | + QString::number( ( serversocket->port() ) & 0xFF ) +")" ); |
537 | } | 537 | } |
538 | 538 | ||
539 | // representation type (TYPE) | 539 | // representation type (TYPE) |
540 | else if ( cmd == "TYPE" ) { | 540 | else if ( cmd == "TYPE" ) { |
541 | if ( arg.upper() == "A" || arg.upper() == "I" ) | 541 | if ( arg.upper() == "A" || arg.upper() == "I" ) |
542 | send( "200 Command okay" ); // No tr | 542 | send( "200 Command okay" ); // No tr |
543 | else | 543 | else |
544 | send( "504 Command not implemented for that parameter" ); // No tr | 544 | send( "504 Command not implemented for that parameter" ); // No tr |
545 | } | 545 | } |
546 | 546 | ||
547 | // file structure (STRU) | 547 | // file structure (STRU) |
548 | else if ( cmd == "STRU" ) { | 548 | else if ( cmd == "STRU" ) { |
549 | if ( arg.upper() == "F" ) | 549 | if ( arg.upper() == "F" ) |
550 | send( "200 Command okay" ); // No tr | 550 | send( "200 Command okay" ); // No tr |
551 | else | 551 | else |
552 | send( "504 Command not implemented for that parameter" ); // No tr | 552 | send( "504 Command not implemented for that parameter" ); // No tr |
553 | } | 553 | } |
554 | 554 | ||
555 | // transfer mode (MODE) | 555 | // transfer mode (MODE) |
556 | else if ( cmd == "MODE" ) { | 556 | else if ( cmd == "MODE" ) { |
557 | if ( arg.upper() == "S" ) | 557 | if ( arg.upper() == "S" ) |
558 | send( "200 Command okay" ); // No tr | 558 | send( "200 Command okay" ); // No tr |
559 | else | 559 | else |
560 | send( "504 Command not implemented for that parameter" ); // No tr | 560 | send( "504 Command not implemented for that parameter" ); // No tr |
561 | } | 561 | } |
562 | 562 | ||
563 | 563 | ||
564 | // FTP SERVICE COMMANDS | 564 | // FTP SERVICE COMMANDS |
565 | 565 | ||
566 | 566 | ||
567 | // retrieve (RETR) | 567 | // retrieve (RETR) |
568 | else if ( cmd == "RETR" ) | 568 | else if ( cmd == "RETR" ) |
569 | if ( !args.isEmpty() && checkReadFile( absFilePath( args ) ) | 569 | if ( !args.isEmpty() && checkReadFile( absFilePath( args ) ) |
570 | || backupRestoreGzip( absFilePath( args ) ) ) { | 570 | || backupRestoreGzip( absFilePath( args ) ) ) { |
571 | send( "150 File status okay" ); // No tr | 571 | send( "150 File status okay" ); // No tr |
572 | sendFile( absFilePath( args ) ); | 572 | sendFile( absFilePath( args ) ); |
573 | } | 573 | } |
574 | else { | 574 | else { |
575 | odebug << "550 Requested action not taken" << oendl; | 575 | odebug << "550 Requested action not taken" << oendl; |
576 | send( "550 Requested action not taken" ); // No tr | 576 | send( "550 Requested action not taken" ); // No tr |
577 | } | 577 | } |
578 | 578 | ||
579 | // store (STOR) | 579 | // store (STOR) |
580 | else if ( cmd == "STOR" ) | 580 | else if ( cmd == "STOR" ) |
581 | if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) { | 581 | if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) { |
582 | send( "150 File status okay" ); // No tr | 582 | send( "150 File status okay" ); // No tr |
583 | retrieveFile( absFilePath( args ) ); | 583 | retrieveFile( absFilePath( args ) ); |
584 | } | 584 | } |
585 | else | 585 | else |
586 | send( "550 Requested action not taken" ); // No tr | 586 | send( "550 Requested action not taken" ); // No tr |
587 | 587 | ||
588 | // store unique (STOU) | 588 | // store unique (STOU) |
589 | else if ( cmd == "STOU" ) { | 589 | else if ( cmd == "STOU" ) { |
590 | send( "502 Command not implemented" ); // No tr | 590 | send( "502 Command not implemented" ); // No tr |
591 | } | 591 | } |
592 | 592 | ||
593 | // append (APPE) | 593 | // append (APPE) |
594 | else if ( cmd == "APPE" ) { | 594 | else if ( cmd == "APPE" ) { |
595 | send( "502 Command not implemented" ); // No tr | 595 | send( "502 Command not implemented" ); // No tr |
596 | } | 596 | } |
597 | 597 | ||
598 | // allocate (ALLO) | 598 | // allocate (ALLO) |
599 | else if ( cmd == "ALLO" ) { | 599 | else if ( cmd == "ALLO" ) { |
600 | storFileSize = args.toInt(); | 600 | storFileSize = args.toInt(); |
601 | send( "200 Command okay" ); // No tr | 601 | send( "200 Command okay" ); // No tr |
602 | } | 602 | } |
603 | 603 | ||
604 | // restart (REST) | 604 | // restart (REST) |
605 | else if ( cmd == "REST" ) { | 605 | else if ( cmd == "REST" ) { |
606 | send( "502 Command not implemented" ); // No tr | 606 | send( "502 Command not implemented" ); // No tr |
607 | } | 607 | } |
608 | 608 | ||
609 | // rename from (RNFR) | 609 | // rename from (RNFR) |
610 | else if ( cmd == "RNFR" ) { | 610 | else if ( cmd == "RNFR" ) { |
611 | renameFrom = QString::null; | 611 | renameFrom = QString::null; |
612 | if ( args.isEmpty() ) | 612 | if ( args.isEmpty() ) |
613 | send( "500 Syntax error, command unrecognized" ); // No tr | 613 | send( "500 Syntax error, command unrecognized" ); // No tr |
614 | else { | 614 | else { |
615 | QFile file( absFilePath( args ) ); | 615 | QFile file( absFilePath( args ) ); |
616 | if ( file.exists() ) { | 616 | if ( file.exists() ) { |
617 | send( "350 File exists, ready for destination name" ); // No tr | 617 | send( "350 File exists, ready for destination name" ); // No tr |
618 | renameFrom = absFilePath( args ); | 618 | renameFrom = absFilePath( args ); |
619 | } | 619 | } |
620 | else | 620 | else |
621 | send( "550 Requested action not taken" ); // No tr | 621 | send( "550 Requested action not taken" ); // No tr |
622 | } | 622 | } |
623 | } | 623 | } |
624 | 624 | ||
625 | // rename to (RNTO) | 625 | // rename to (RNTO) |
626 | else if ( cmd == "RNTO" ) { | 626 | else if ( cmd == "RNTO" ) { |
627 | if ( lastCommand != "RNFR" ) | 627 | if ( lastCommand != "RNFR" ) |
628 | send( "503 Bad sequence of commands" ); // No tr | 628 | send( "503 Bad sequence of commands" ); // No tr |
629 | else if ( args.isEmpty() ) | 629 | else if ( args.isEmpty() ) |
630 | send( "500 Syntax error, command unrecognized" ); // No tr | 630 | send( "500 Syntax error, command unrecognized" ); // No tr |
631 | else { | 631 | else { |
632 | QDir dir( absFilePath( args ) ); | 632 | QDir dir( absFilePath( args ) ); |
633 | if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) | 633 | if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) |
634 | send( "250 Requested file action okay, completed." ); // No tr | 634 | send( "250 Requested file action okay, completed." ); // No tr |
635 | else | 635 | else |
636 | send( "550 Requested action not taken" ); // No tr | 636 | send( "550 Requested action not taken" ); // No tr |
637 | } | 637 | } |
638 | } | 638 | } |
639 | 639 | ||
640 | // abort (ABOR) | 640 | // abort (ABOR) |
641 | else if ( cmd.contains( "ABOR" ) ) { | 641 | else if ( cmd.contains( "ABOR" ) ) { |
642 | dtp->close(); | 642 | dtp->close(); |
643 | if ( dtp->dtpMode() != ServerDTP::Idle ) | 643 | if ( dtp->dtpMode() != ServerDTP::Idle ) |
644 | send( "426 Connection closed; transfer aborted" ); // No tr | 644 | send( "426 Connection closed; transfer aborted" ); // No tr |
645 | else | 645 | else |
646 | send( "226 Closing data connection" ); // No tr | 646 | send( "226 Closing data connection" ); // No tr |
647 | } | 647 | } |
648 | 648 | ||
649 | // delete (DELE) | 649 | // delete (DELE) |
650 | else if ( cmd == "DELE" ) { | 650 | else if ( cmd == "DELE" ) { |
651 | if ( args.isEmpty() ) | 651 | if ( args.isEmpty() ) |
652 | send( "500 Syntax error, command unrecognized" ); // No tr | 652 | send( "500 Syntax error, command unrecognized" ); // No tr |
653 | else { | 653 | else { |
654 | QFile file( absFilePath( args ) ) ; | 654 | QFile file( absFilePath( args ) ) ; |
655 | if ( file.remove() ) { | 655 | if ( file.remove() ) { |
656 | send( "250 Requested file action okay, completed" ); // No tr | 656 | send( "250 Requested file action okay, completed" ); // No tr |
657 | QCopEnvelope e("QPE/System", "linkChanged(QString)" ); | 657 | QCopEnvelope e("QPE/System", "linkChanged(QString)" ); |
658 | e << file.name(); | 658 | e << file.name(); |
659 | } else { | 659 | } else { |
660 | send( "550 Requested action not taken" ); // No tr | 660 | send( "550 Requested action not taken" ); // No tr |
661 | } | 661 | } |
662 | } | 662 | } |
663 | } | 663 | } |
664 | 664 | ||
665 | // remove directory (RMD) | 665 | // remove directory (RMD) |
666 | else if ( cmd == "RMD" ) { | 666 | else if ( cmd == "RMD" ) { |
667 | if ( args.isEmpty() ) | 667 | if ( args.isEmpty() ) |
668 | send( "500 Syntax error, command unrecognized" ); // No tr | 668 | send( "500 Syntax error, command unrecognized" ); // No tr |
669 | else { | 669 | else { |
670 | QDir dir; | 670 | QDir dir; |
671 | if ( dir.rmdir( absFilePath( args ), TRUE ) ) | 671 | if ( dir.rmdir( absFilePath( args ), TRUE ) ) |
672 | send( "250 Requested file action okay, completed" ); // No tr | 672 | send( "250 Requested file action okay, completed" ); // No tr |
673 | else | 673 | else |
674 | send( "550 Requested action not taken" ); // No tr | 674 | send( "550 Requested action not taken" ); // No tr |
675 | } | 675 | } |
676 | } | 676 | } |
677 | 677 | ||
678 | // make directory (MKD) | 678 | // make directory (MKD) |
679 | else if ( cmd == "MKD" ) { | 679 | else if ( cmd == "MKD" ) { |
680 | if ( args.isEmpty() ) { | 680 | if ( args.isEmpty() ) { |
681 | odebug << " Error: no arg" << oendl; | 681 | odebug << " Error: no arg" << oendl; |
682 | send( "500 Syntax error, command unrecognized" ); // No tr | 682 | send( "500 Syntax error, command unrecognized" ); // No tr |
683 | } | 683 | } |
684 | else { | 684 | else { |
685 | QDir dir; | 685 | QDir dir; |
686 | if ( dir.mkdir( absFilePath( args ), TRUE ) ) | 686 | if ( dir.mkdir( absFilePath( args ), TRUE ) ) |
687 | send( "250 Requested file action okay, completed." ); // No tr | 687 | send( "250 Requested file action okay, completed." ); // No tr |
688 | else | 688 | else |
689 | send( "550 Requested action not taken" ); // No tr | 689 | send( "550 Requested action not taken" ); // No tr |
690 | } | 690 | } |
691 | } | 691 | } |
692 | 692 | ||
693 | // print working directory (PWD) | 693 | // print working directory (PWD) |
694 | else if ( cmd == "PWD" ) { | 694 | else if ( cmd == "PWD" ) { |
695 | send( "257 \"" + directory.path() +"\"" ); | 695 | send( "257 \"" + directory.path() +"\"" ); |
696 | } | 696 | } |
697 | 697 | ||
698 | // list (LIST) | 698 | // list (LIST) |
699 | else if ( cmd == "LIST" ) { | 699 | else if ( cmd == "LIST" ) { |
700 | if ( sendList( absFilePath( args ) ) ) | 700 | if ( sendList( absFilePath( args ) ) ) |
701 | send( "150 File status okay" ); // No tr | 701 | send( "150 File status okay" ); // No tr |
702 | else | 702 | else |
703 | send( "500 Syntax error, command unrecognized" ); // No tr | 703 | send( "500 Syntax error, command unrecognized" ); // No tr |
704 | } | 704 | } |
705 | 705 | ||
706 | // size (SIZE) | 706 | // size (SIZE) |
707 | else if ( cmd == "SIZE" ) { | 707 | else if ( cmd == "SIZE" ) { |
708 | QString filePath = absFilePath( args ); | 708 | QString filePath = absFilePath( args ); |
709 | QFileInfo fi( filePath ); | 709 | QFileInfo fi( filePath ); |
710 | bool gzipfile = backupRestoreGzip( filePath ); | 710 | bool gzipfile = backupRestoreGzip( filePath ); |
711 | if ( !fi.exists() && !gzipfile ) | 711 | if ( !fi.exists() && !gzipfile ) |
712 | send( "500 Syntax error, command unrecognized" ); // No tr | 712 | send( "500 Syntax error, command unrecognized" ); // No tr |
713 | else { | 713 | else { |
714 | if ( !gzipfile ) | 714 | if ( !gzipfile ) |
715 | send( "213 " + QString::number( fi.size() ) ); | 715 | send( "213 " + QString::number( fi.size() ) ); |
716 | else { | 716 | else { |
717 | Process duproc( QString("du") ); | 717 | Process duproc( QString("du") ); |
718 | duproc.addArgument("-s"); | 718 | duproc.addArgument("-s"); |
719 | QString in, out; | 719 | QString in, out; |
720 | if ( !duproc.exec(in, out) ) { | 720 | if ( !duproc.exec(in, out) ) { |
721 | odebug << "du process failed; just sending back 1K" << oendl; | 721 | odebug << "du process failed; just sending back 1K" << oendl; |
722 | send( "213 1024"); | 722 | send( "213 1024"); |
723 | } | 723 | } |
724 | else { | 724 | else { |
725 | QString size = out.left( out.find("\t") ); | 725 | QString size = out.left( out.find("\t") ); |
726 | int guess = size.toInt()/5; | 726 | int guess = size.toInt()/5; |
727 | if ( filePath.contains("doc") ) // No tr | 727 | if ( filePath.contains("doc") ) // No tr |
728 | guess *= 1000; | 728 | guess *= 1000; |
729 | odebug << "sending back gzip guess of " << guess << "" << oendl; | 729 | odebug << "sending back gzip guess of " << guess << "" << oendl; |
730 | send( "213 " + QString::number(guess) ); | 730 | send( "213 " + QString::number(guess) ); |
731 | } | 731 | } |
732 | } | 732 | } |
733 | } | 733 | } |
734 | } | 734 | } |
735 | // name list (NLST) | 735 | // name list (NLST) |
736 | else if ( cmd == "NLST" ) { | 736 | else if ( cmd == "NLST" ) { |
737 | send( "502 Command not implemented" ); // No tr | 737 | send( "502 Command not implemented" ); // No tr |
738 | } | 738 | } |
739 | 739 | ||
740 | // site parameters (SITE) | 740 | // site parameters (SITE) |
741 | else if ( cmd == "SITE" ) { | 741 | else if ( cmd == "SITE" ) { |
742 | send( "502 Command not implemented" ); // No tr | 742 | send( "502 Command not implemented" ); // No tr |
743 | } | 743 | } |
744 | 744 | ||
745 | // system (SYST) | 745 | // system (SYST) |
746 | else if ( cmd == "SYST" ) { | 746 | else if ( cmd == "SYST" ) { |
747 | send( "215 UNIX Type: L8" ); // No tr | 747 | send( "215 UNIX Type: L8" ); // No tr |
748 | } | 748 | } |
749 | 749 | ||
750 | // status (STAT) | 750 | // status (STAT) |
751 | else if ( cmd == "STAT" ) { | 751 | else if ( cmd == "STAT" ) { |
752 | send( "502 Command not implemented" ); // No tr | 752 | send( "502 Command not implemented" ); // No tr |
753 | } | 753 | } |
754 | 754 | ||
755 | // help (HELP ) | 755 | // help (HELP ) |
756 | else if ( cmd == "HELP" ) { | 756 | else if ( cmd == "HELP" ) { |
757 | send( "502 Command not implemented" ); // No tr | 757 | send( "502 Command not implemented" ); // No tr |
758 | } | 758 | } |
759 | 759 | ||
760 | // noop (NOOP) | 760 | // noop (NOOP) |
761 | else if ( cmd == "NOOP" ) { | 761 | else if ( cmd == "NOOP" ) { |
762 | send( "200 Command okay" ); // No tr | 762 | send( "200 Command okay" ); // No tr |
763 | } | 763 | } |
764 | 764 | ||
765 | // not implemented | 765 | // not implemented |
766 | else | 766 | else |
767 | send( "502 Command not implemented" ); // No tr | 767 | send( "502 Command not implemented" ); // No tr |
768 | 768 | ||
769 | lastCommand = cmd; | 769 | lastCommand = cmd; |
770 | } | 770 | } |
771 | 771 | ||
772 | bool ServerPI::backupRestoreGzip( const QString &file ) | 772 | bool ServerPI::backupRestoreGzip( const QString &file ) |
773 | { | 773 | { |
774 | return (file.find( "backup" ) != -1 && // No tr | 774 | return (file.find( "backup" ) != -1 && // No tr |
775 | file.findRev( ".tgz" ) == (int)file.length()-4 ); | 775 | file.findRev( ".tgz" ) == (int)file.length()-4 ); |
776 | } | 776 | } |
777 | 777 | ||
778 | bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets ) | 778 | bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets ) |
779 | { | 779 | { |
780 | if ( file.find( "backup" ) != -1 && // No tr | 780 | if ( file.find( "backup" ) != -1 && // No tr |
781 | file.findRev( ".tgz" ) == (int)file.length()-4 ) { | 781 | file.findRev( ".tgz" ) == (int)file.length()-4 ) { |
782 | QFileInfo info( file ); | 782 | QFileInfo info( file ); |
783 | targets = info.dirPath( TRUE ); | 783 | targets = info.dirPath( TRUE ); |
784 | qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(), | 784 | odebug << "ServerPI::backupRestoreGzip for " << file.latin1() << " = " << targets.join(" ").latin1() << oendl; |
785 | targets.join(" ").latin1() ); | ||
786 | return true; | 785 | return true; |
787 | } | 786 | } |
788 | return false; | 787 | return false; |
789 | } | 788 | } |
790 | 789 | ||
791 | void ServerPI::sendFile( const QString& file ) | 790 | void ServerPI::sendFile( const QString& file ) |
792 | { | 791 | { |
793 | if ( passiv ) { | 792 | if ( passiv ) { |
794 | wait[SendFile] = TRUE; | 793 | wait[SendFile] = TRUE; |
795 | waitfile = file; | 794 | waitfile = file; |
796 | if ( waitsocket ) | 795 | if ( waitsocket ) |
797 | newConnection( waitsocket ); | 796 | newConnection( waitsocket ); |
798 | } | 797 | } |
799 | else { | 798 | else { |
800 | QStringList targets; | 799 | QStringList targets; |
801 | if ( backupRestoreGzip( file, targets ) ) | 800 | if ( backupRestoreGzip( file, targets ) ) |
802 | dtp->sendGzipFile( file, targets, peeraddress, peerport ); | 801 | dtp->sendGzipFile( file, targets, peeraddress, peerport ); |
803 | else dtp->sendFile( file, peeraddress, peerport ); | 802 | else dtp->sendFile( file, peeraddress, peerport ); |
804 | } | 803 | } |
805 | } | 804 | } |
806 | 805 | ||
807 | void ServerPI::retrieveFile( const QString& file ) | 806 | void ServerPI::retrieveFile( const QString& file ) |
808 | { | 807 | { |
809 | if ( passiv ) { | 808 | if ( passiv ) { |
810 | wait[RetrieveFile] = TRUE; | 809 | wait[RetrieveFile] = TRUE; |
811 | waitfile = file; | 810 | waitfile = file; |
812 | if ( waitsocket ) | 811 | if ( waitsocket ) |
813 | newConnection( waitsocket ); | 812 | newConnection( waitsocket ); |
814 | } | 813 | } |
815 | else { | 814 | else { |
816 | QStringList targets; | 815 | QStringList targets; |
817 | if ( backupRestoreGzip( file, targets ) ) | 816 | if ( backupRestoreGzip( file, targets ) ) |
818 | dtp->retrieveGzipFile( file, peeraddress, peerport ); | 817 | dtp->retrieveGzipFile( file, peeraddress, peerport ); |
819 | else | 818 | else |
820 | dtp->retrieveFile( file, peeraddress, peerport, storFileSize ); | 819 | dtp->retrieveFile( file, peeraddress, peerport, storFileSize ); |
821 | } | 820 | } |
822 | } | 821 | } |
823 | 822 | ||
824 | bool ServerPI::parsePort( const QString& pp ) | 823 | bool ServerPI::parsePort( const QString& pp ) |
825 | { | 824 | { |
826 | QStringList p = QStringList::split( ",", pp ); | 825 | QStringList p = QStringList::split( ",", pp ); |
827 | if ( p.count() != 6 ) return FALSE; | 826 | if ( p.count() != 6 ) return FALSE; |
828 | 827 | ||
829 | // h1,h2,h3,h4,p1,p2 | 828 | // h1,h2,h3,h4,p1,p2 |
830 | peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + | 829 | peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + |
831 | ( p[2].toInt() << 8 ) + p[3].toInt() ); | 830 | ( p[2].toInt() << 8 ) + p[3].toInt() ); |
832 | peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); | 831 | peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); |
833 | return TRUE; | 832 | return TRUE; |
834 | } | 833 | } |
835 | 834 | ||
836 | void ServerPI::dtpCompleted() | 835 | void ServerPI::dtpCompleted() |
837 | { | 836 | { |
838 | send( "226 Closing data connection, file transfer successful" ); // No tr | 837 | send( "226 Closing data connection, file transfer successful" ); // No tr |
839 | if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) { | 838 | if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) { |
840 | QString fn = dtp->fileName(); | 839 | QString fn = dtp->fileName(); |
841 | if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { | 840 | if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { |
842 | QCopEnvelope e("QPE/System", "linkChanged(QString)" ); | 841 | QCopEnvelope e("QPE/System", "linkChanged(QString)" ); |
843 | e << fn; | 842 | e << fn; |
844 | } | 843 | } |
845 | } | 844 | } |
846 | waitsocket = 0; | 845 | waitsocket = 0; |
847 | dtp->close(); | 846 | dtp->close(); |
848 | storFileSize = -1; | 847 | storFileSize = -1; |
849 | } | 848 | } |
850 | 849 | ||
851 | void ServerPI::dtpFailed() | 850 | void ServerPI::dtpFailed() |
852 | { | 851 | { |
853 | dtp->close(); | 852 | dtp->close(); |
854 | waitsocket = 0; | 853 | waitsocket = 0; |
855 | send( "451 Requested action aborted: local error in processing" ); // No tr | 854 | send( "451 Requested action aborted: local error in processing" ); // No tr |
856 | storFileSize = -1; | 855 | storFileSize = -1; |
857 | } | 856 | } |
858 | 857 | ||
859 | void ServerPI::dtpError( int ) | 858 | void ServerPI::dtpError( int ) |
860 | { | 859 | { |
861 | dtp->close(); | 860 | dtp->close(); |
862 | waitsocket = 0; | 861 | waitsocket = 0; |
863 | send( "451 Requested action aborted: local error in processing" ); // No tr | 862 | send( "451 Requested action aborted: local error in processing" ); // No tr |
864 | storFileSize = -1; | 863 | storFileSize = -1; |
865 | } | 864 | } |
866 | 865 | ||
867 | bool ServerPI::sendList( const QString& arg ) | 866 | bool ServerPI::sendList( const QString& arg ) |
868 | { | 867 | { |
869 | QByteArray listing; | 868 | QByteArray listing; |
870 | QBuffer buffer( listing ); | 869 | QBuffer buffer( listing ); |
871 | 870 | ||
872 | if ( !buffer.open( IO_WriteOnly ) ) | 871 | if ( !buffer.open( IO_WriteOnly ) ) |
873 | return FALSE; | 872 | return FALSE; |
874 | 873 | ||
875 | QTextStream ts( &buffer ); | 874 | QTextStream ts( &buffer ); |
876 | QString fn = arg; | 875 | QString fn = arg; |
877 | 876 | ||
878 | if ( fn.isEmpty() ) | 877 | if ( fn.isEmpty() ) |
879 | fn = directory.path(); | 878 | fn = directory.path(); |
880 | 879 | ||
881 | QFileInfo fi( fn ); | 880 | QFileInfo fi( fn ); |
882 | if ( !fi.exists() ) return FALSE; | 881 | if ( !fi.exists() ) return FALSE; |
883 | 882 | ||
884 | // return file listing | 883 | // return file listing |
885 | if ( fi.isFile() ) { | 884 | if ( fi.isFile() ) { |
886 | ts << fileListing( &fi ) << endl; | 885 | ts << fileListing( &fi ) << endl; |
887 | } | 886 | } |
888 | 887 | ||
889 | // return directory listing | 888 | // return directory listing |
890 | else if ( fi.isDir() ) { | 889 | else if ( fi.isDir() ) { |
891 | QDir dir( fn ); | 890 | QDir dir( fn ); |
892 | const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); | 891 | const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); |
893 | 892 | ||
894 | QFileInfoListIterator it( *list ); | 893 | QFileInfoListIterator it( *list ); |
895 | QFileInfo *info; | 894 | QFileInfo *info; |
896 | 895 | ||
897 | unsigned long total = 0; | 896 | unsigned long total = 0; |
898 | while ( ( info = it.current() ) ) { | 897 | while ( ( info = it.current() ) ) { |
899 | if ( info->fileName() != "." && info->fileName() != ".." ) | 898 | if ( info->fileName() != "." && info->fileName() != ".." ) |
900 | total += info->size(); | 899 | total += info->size(); |
901 | ++it; | 900 | ++it; |
902 | } | 901 | } |
903 | 902 | ||
904 | ts << "total " << QString::number( total / 1024 ) << endl; // No tr | 903 | ts << "total " << QString::number( total / 1024 ) << endl; // No tr |
905 | 904 | ||
906 | it.toFirst(); | 905 | it.toFirst(); |
907 | while ( ( info = it.current() ) ) { | 906 | while ( ( info = it.current() ) ) { |
908 | if ( info->fileName() == "." || info->fileName() == ".." ) { | 907 | if ( info->fileName() == "." || info->fileName() == ".." ) { |
909 | ++it; | 908 | ++it; |
910 | continue; | 909 | continue; |
911 | } | 910 | } |
912 | ts << fileListing( info ) << endl; | 911 | ts << fileListing( info ) << endl; |
913 | ++it; | 912 | ++it; |
914 | } | 913 | } |
915 | } | 914 | } |
916 | 915 | ||
917 | if ( passiv ) { | 916 | if ( passiv ) { |
918 | waitarray = buffer.buffer(); | 917 | waitarray = buffer.buffer(); |
919 | wait[SendByteArray] = TRUE; | 918 | wait[SendByteArray] = TRUE; |
920 | if ( waitsocket ) | 919 | if ( waitsocket ) |
921 | newConnection( waitsocket ); | 920 | newConnection( waitsocket ); |
922 | } | 921 | } |
923 | else | 922 | else |
924 | dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); | 923 | dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); |
925 | return TRUE; | 924 | return TRUE; |
926 | } | 925 | } |
927 | 926 | ||
928 | QString ServerPI::fileListing( QFileInfo *info ) | 927 | QString ServerPI::fileListing( QFileInfo *info ) |
929 | { | 928 | { |
930 | if ( !info ) return QString::null; | 929 | if ( !info ) return QString::null; |
931 | QString s; | 930 | QString s; |
932 | 931 | ||
933 | // type char | 932 | // type char |
934 | if ( info->isDir() ) | 933 | if ( info->isDir() ) |
935 | s += "d"; | 934 | s += "d"; |
936 | else if ( info->isSymLink() ) | 935 | else if ( info->isSymLink() ) |
937 | s += "l"; | 936 | s += "l"; |
938 | else | 937 | else |
939 | s += "-"; | 938 | s += "-"; |
940 | 939 | ||
941 | // permisson string | 940 | // permisson string |
942 | s += permissionString( info ) + " "; | 941 | s += permissionString( info ) + " "; |
943 | 942 | ||
944 | // number of hardlinks | 943 | // number of hardlinks |
945 | int subdirs = 1; | 944 | int subdirs = 1; |
946 | 945 | ||
947 | if ( info->isDir() ) | 946 | if ( info->isDir() ) |
948 | subdirs = 2; | 947 | subdirs = 2; |
949 | // FIXME : this is to slow | 948 | // FIXME : this is to slow |
950 | //if ( info->isDir() ) | 949 | //if ( info->isDir() ) |
951 | //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count(); | 950 | //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count(); |
952 | 951 | ||
953 | s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " "; | 952 | s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " "; |
954 | 953 | ||
955 | // owner | 954 | // owner |
956 | QString o = info->owner(); | 955 | QString o = info->owner(); |
957 | if ( o.isEmpty() ) | 956 | if ( o.isEmpty() ) |
958 | o = QString::number(info->ownerId()); | 957 | o = QString::number(info->ownerId()); |
959 | s += o.leftJustify( 8, ' ', TRUE ) + " "; | 958 | s += o.leftJustify( 8, ' ', TRUE ) + " "; |
960 | 959 | ||
961 | // group | 960 | // group |
962 | QString g = info->group(); | 961 | QString g = info->group(); |
963 | if ( g.isEmpty() ) | 962 | if ( g.isEmpty() ) |
964 | g = QString::number(info->groupId()); | 963 | g = QString::number(info->groupId()); |
965 | s += g.leftJustify( 8, ' ', TRUE ) + " "; | 964 | s += g.leftJustify( 8, ' ', TRUE ) + " "; |
966 | 965 | ||
967 | // file size in bytes | 966 | // file size in bytes |
968 | s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " "; | 967 | s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " "; |
969 | 968 | ||
970 | // last modified date | 969 | // last modified date |
971 | QDate date = info->lastModified().date(); | 970 | QDate date = info->lastModified().date(); |
972 | QTime time = info->lastModified().time(); | 971 | QTime time = info->lastModified().time(); |
973 | s += date.monthName( date.month() ) + " " | 972 | s += date.monthName( date.month() ) + " " |
974 | + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " " | 973 | + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " " |
975 | + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":" | 974 | + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":" |
976 | + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " "; | 975 | + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " "; |
977 | 976 | ||
978 | // file name | 977 | // file name |
979 | s += info->fileName(); | 978 | s += info->fileName(); |
980 | 979 | ||
981 | return s; | 980 | return s; |
982 | } | 981 | } |
983 | 982 | ||
984 | QString ServerPI::permissionString( QFileInfo *info ) | 983 | QString ServerPI::permissionString( QFileInfo *info ) |
985 | { | 984 | { |
986 | if ( !info ) return QString( "---------" ); | 985 | if ( !info ) return QString( "---------" ); |
987 | QString s; | 986 | QString s; |
988 | 987 | ||
989 | // user | 988 | // user |
990 | if ( info->permission( QFileInfo::ReadUser ) ) s += "r"; | 989 | if ( info->permission( QFileInfo::ReadUser ) ) s += "r"; |
991 | else s += "-"; | 990 | else s += "-"; |
992 | if ( info->permission( QFileInfo::WriteUser ) ) s += "w"; | 991 | if ( info->permission( QFileInfo::WriteUser ) ) s += "w"; |
993 | else s += "-"; | 992 | else s += "-"; |
994 | if ( info->permission( QFileInfo::ExeUser ) ) s += "x"; | 993 | if ( info->permission( QFileInfo::ExeUser ) ) s += "x"; |
995 | else s += "-"; | 994 | else s += "-"; |
996 | 995 | ||
997 | // group | 996 | // group |
998 | if ( info->permission( QFileInfo::ReadGroup ) ) s += "r"; | 997 | if ( info->permission( QFileInfo::ReadGroup ) ) s += "r"; |
999 | else s += "-"; | 998 | else s += "-"; |
1000 | if ( info->permission( QFileInfo::WriteGroup ) )s += "w"; | 999 | if ( info->permission( QFileInfo::WriteGroup ) )s += "w"; |
1001 | else s += "-"; | 1000 | else s += "-"; |
1002 | if ( info->permission( QFileInfo::ExeGroup ) ) s += "x"; | 1001 | if ( info->permission( QFileInfo::ExeGroup ) ) s += "x"; |
1003 | else s += "-"; | 1002 | else s += "-"; |
1004 | 1003 | ||
1005 | // exec | 1004 | // exec |
1006 | if ( info->permission( QFileInfo::ReadOther ) ) s += "r"; | 1005 | if ( info->permission( QFileInfo::ReadOther ) ) s += "r"; |
1007 | else s += "-"; | 1006 | else s += "-"; |
1008 | if ( info->permission( QFileInfo::WriteOther ) ) s += "w"; | 1007 | if ( info->permission( QFileInfo::WriteOther ) ) s += "w"; |
1009 | else s += "-"; | 1008 | else s += "-"; |
1010 | if ( info->permission( QFileInfo::ExeOther ) ) s += "x"; | 1009 | if ( info->permission( QFileInfo::ExeOther ) ) s += "x"; |
1011 | else s += "-"; | 1010 | else s += "-"; |
1012 | 1011 | ||
1013 | return s; | 1012 | return s; |
1014 | } | 1013 | } |
1015 | 1014 | ||
1016 | void ServerPI::newConnection( int socket ) | 1015 | void ServerPI::newConnection( int socket ) |
1017 | { | 1016 | { |
1018 | //odebug << "New incomming connection" << oendl; | 1017 | //odebug << "New incomming connection" << oendl; |
1019 | 1018 | ||
1020 | if ( !passiv ) return; | 1019 | if ( !passiv ) return; |
1021 | 1020 | ||
1022 | if ( wait[SendFile] ) { | 1021 | if ( wait[SendFile] ) { |
1023 | QStringList targets; | 1022 | QStringList targets; |
1024 | if ( backupRestoreGzip( waitfile, targets ) ) | 1023 | if ( backupRestoreGzip( waitfile, targets ) ) |
1025 | dtp->sendGzipFile( waitfile, targets ); | 1024 | dtp->sendGzipFile( waitfile, targets ); |
1026 | else | 1025 | else |
1027 | dtp->sendFile( waitfile ); | 1026 | dtp->sendFile( waitfile ); |
1028 | dtp->setSocket( socket ); | 1027 | dtp->setSocket( socket ); |
1029 | } | 1028 | } |
1030 | else if ( wait[RetrieveFile] ) { | 1029 | else if ( wait[RetrieveFile] ) { |
1031 | odebug << "check retrieve file" << oendl; | 1030 | odebug << "check retrieve file" << oendl; |
1032 | if ( backupRestoreGzip( waitfile ) ) | 1031 | if ( backupRestoreGzip( waitfile ) ) |
1033 | dtp->retrieveGzipFile( waitfile ); | 1032 | dtp->retrieveGzipFile( waitfile ); |
1034 | else | 1033 | else |
1035 | dtp->retrieveFile( waitfile, storFileSize ); | 1034 | dtp->retrieveFile( waitfile, storFileSize ); |
1036 | dtp->setSocket( socket ); | 1035 | dtp->setSocket( socket ); |
1037 | } | 1036 | } |
1038 | else if ( wait[SendByteArray] ) { | 1037 | else if ( wait[SendByteArray] ) { |
1039 | dtp->sendByteArray( waitarray ); | 1038 | dtp->sendByteArray( waitarray ); |
1040 | dtp->setSocket( socket ); | 1039 | dtp->setSocket( socket ); |
1041 | } | 1040 | } |
1042 | else if ( wait[RetrieveByteArray] ) { | 1041 | else if ( wait[RetrieveByteArray] ) { |
1043 | odebug << "retrieve byte array" << oendl; | 1042 | odebug << "retrieve byte array" << oendl; |
1044 | dtp->retrieveByteArray(); | 1043 | dtp->retrieveByteArray(); |
1045 | dtp->setSocket( socket ); | 1044 | dtp->setSocket( socket ); |
1046 | } | 1045 | } |
1047 | else | 1046 | else |
1048 | waitsocket = socket; | 1047 | waitsocket = socket; |
1049 | 1048 | ||
1050 | for( int i = 0; i < 4; i++ ) | 1049 | for( int i = 0; i < 4; i++ ) |
1051 | wait[i] = FALSE; | 1050 | wait[i] = FALSE; |
1052 | } | 1051 | } |
1053 | 1052 | ||
1054 | QString ServerPI::absFilePath( const QString& file ) | 1053 | QString ServerPI::absFilePath( const QString& file ) |
1055 | { | 1054 | { |
1056 | if ( file.isEmpty() ) return file; | 1055 | if ( file.isEmpty() ) return file; |
1057 | 1056 | ||
1058 | QString filepath( file ); | 1057 | QString filepath( file ); |
1059 | if ( file[0] != "/" ) | 1058 | if ( file[0] != "/" ) |
1060 | filepath = directory.path() + "/" + file; | 1059 | filepath = directory.path() + "/" + file; |
1061 | 1060 | ||
1062 | return filepath; | 1061 | return filepath; |
1063 | } | 1062 | } |
1064 | 1063 | ||
1065 | 1064 | ||
1066 | void ServerPI::timerEvent( QTimerEvent * ) | 1065 | void ServerPI::timerEvent( QTimerEvent * ) |
1067 | { | 1066 | { |
1068 | connectionClosed(); | 1067 | connectionClosed(); |
1069 | } | 1068 | } |
1070 | 1069 | ||
1071 | 1070 | ||
1072 | ServerDTP::ServerDTP( QObject *parent, const char* name) | 1071 | ServerDTP::ServerDTP( QObject *parent, const char* name) |
1073 | : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), | 1072 | : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), |
1074 | retrieveTargzProc( 0 ) | 1073 | retrieveTargzProc( 0 ) |
1075 | { | 1074 | { |
1076 | 1075 | ||
1077 | connect( this, SIGNAL( connected() ), SLOT( connected() ) ); | 1076 | connect( this, SIGNAL( connected() ), SLOT( connected() ) ); |
1078 | connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); | 1077 | connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); |
1079 | connect( this, SIGNAL( bytesWritten(int) ), SLOT( bytesWritten(int) ) ); | 1078 | connect( this, SIGNAL( bytesWritten(int) ), SLOT( bytesWritten(int) ) ); |
1080 | connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); | 1079 | connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); |
1081 | 1080 | ||
1082 | createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); // No tr | 1081 | createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); // No tr |
1083 | createTargzProc->setCommunication( QProcess::Stdout ); | 1082 | createTargzProc->setCommunication( QProcess::Stdout ); |
1084 | createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); | 1083 | createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); |
1085 | connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); | 1084 | connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); |
1086 | 1085 | ||
1087 | retrieveTargzProc = new QProcess( this, "retrieveTargzProc" ); | 1086 | retrieveTargzProc = new QProcess( this, "retrieveTargzProc" ); |
1088 | retrieveTargzProc->setCommunication( QProcess::Stdin ); | 1087 | retrieveTargzProc->setCommunication( QProcess::Stdin ); |
1089 | retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); | 1088 | retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); |
1090 | connect( retrieveTargzProc, SIGNAL( processExited() ), | 1089 | connect( retrieveTargzProc, SIGNAL( processExited() ), |
1091 | SIGNAL( completed() ) ); | 1090 | SIGNAL( completed() ) ); |
1092 | connect( retrieveTargzProc, SIGNAL( processExited() ), | 1091 | connect( retrieveTargzProc, SIGNAL( processExited() ), |
1093 | SLOT( extractTarDone() ) ); | 1092 | SLOT( extractTarDone() ) ); |
1094 | } | 1093 | } |
1095 | 1094 | ||
1096 | ServerDTP::~ServerDTP() | 1095 | ServerDTP::~ServerDTP() |
1097 | { | 1096 | { |
1098 | buf.close(); | 1097 | buf.close(); |
1099 | if ( RetrieveFile == mode && file.isOpen() ) { | 1098 | if ( RetrieveFile == mode && file.isOpen() ) { |
1100 | // We're being shutdown before the client closed. | 1099 | // We're being shutdown before the client closed. |
1101 | file.close(); | 1100 | file.close(); |
1102 | if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { | 1101 | if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { |
1103 | odebug << "STOR incomplete" << oendl; | 1102 | odebug << "STOR incomplete" << oendl; |
1104 | file.remove(); | 1103 | file.remove(); |
1105 | } | 1104 | } |
1106 | } else { | 1105 | } else { |
1107 | file.close(); | 1106 | file.close(); |
1108 | } | 1107 | } |
1109 | createTargzProc->kill(); | 1108 | createTargzProc->kill(); |
1110 | } | 1109 | } |
1111 | 1110 | ||
1112 | void ServerDTP::extractTarDone() | 1111 | void ServerDTP::extractTarDone() |
1113 | { | 1112 | { |
1114 | odebug << "extract done" << oendl; | 1113 | odebug << "extract done" << oendl; |
1115 | #ifndef QT_NO_COP | 1114 | #ifndef QT_NO_COP |
1116 | QCopEnvelope e( "QPE/System", "restoreDone(QString)" ); | 1115 | QCopEnvelope e( "QPE/System", "restoreDone(QString)" ); |
1117 | e << file.name(); | 1116 | e << file.name(); |
1118 | #endif | 1117 | #endif |
1119 | } | 1118 | } |
1120 | 1119 | ||
1121 | void ServerDTP::connected() | 1120 | void ServerDTP::connected() |
1122 | { | 1121 | { |
1123 | // send file mode | 1122 | // send file mode |
1124 | switch ( mode ) { | 1123 | switch ( mode ) { |
1125 | case SendFile : | 1124 | case SendFile : |
1126 | if ( !file.exists() || !file.open( IO_ReadOnly) ) { | 1125 | if ( !file.exists() || !file.open( IO_ReadOnly) ) { |
1127 | emit failed(); | 1126 | emit failed(); |
1128 | mode = Idle; | 1127 | mode = Idle; |
1129 | return; | 1128 | return; |
1130 | } | 1129 | } |
1131 | 1130 | ||
1132 | //odebug << "Debug: Sending file '" << file.name() << "'" << oendl; | 1131 | //odebug << "Debug: Sending file '" << file.name() << "'" << oendl; |
1133 | 1132 | ||
1134 | bytes_written = 0; | 1133 | bytes_written = 0; |
1135 | if ( file.size() == 0 ) { | 1134 | if ( file.size() == 0 ) { |
1136 | //make sure it doesn't hang on empty files | 1135 | //make sure it doesn't hang on empty files |
1137 | file.close(); | 1136 | file.close(); |
1138 | emit completed(); | 1137 | emit completed(); |
1139 | mode = Idle; | 1138 | mode = Idle; |
1140 | } else { | 1139 | } else { |
1141 | // Don't write more if there is plenty buffered already. | 1140 | // Don't write more if there is plenty buffered already. |
1142 | if ( bytesToWrite() <= block_size && !file.atEnd() ) { | 1141 | if ( bytesToWrite() <= block_size && !file.atEnd() ) { |
1143 | QCString s; | 1142 | QCString s; |
1144 | s.resize( block_size ); | 1143 | s.resize( block_size ); |
1145 | int bytes = file.readBlock( s.data(), block_size ); | 1144 | int bytes = file.readBlock( s.data(), block_size ); |
1146 | writeBlock( s.data(), bytes ); | 1145 | writeBlock( s.data(), bytes ); |
1147 | } | 1146 | } |
1148 | } | 1147 | } |
1149 | break; | 1148 | break; |
1150 | case SendGzipFile: | 1149 | case SendGzipFile: |
1151 | if ( createTargzProc->isRunning() ) { | 1150 | if ( createTargzProc->isRunning() ) { |
1152 | // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY | 1151 | // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY |
1153 | owarn << "Previous tar --gzip process is still running; killing it..." << oendl; | 1152 | owarn << "Previous tar --gzip process is still running; killing it..." << oendl; |
1154 | createTargzProc->kill(); | 1153 | createTargzProc->kill(); |
1155 | } | 1154 | } |
1156 | 1155 | ||
1157 | bytes_written = 0; | 1156 | bytes_written = 0; |
1158 | odebug << "==>start send tar process" << oendl; | 1157 | odebug << "==>start send tar process" << oendl; |
1159 | if ( !createTargzProc->start() ) | 1158 | if ( !createTargzProc->start() ) |
1160 | qWarning("Error starting %s", | 1159 | qWarning("Error starting %s", |
1161 | createTargzProc->arguments().join(" ").latin1()); | 1160 | createTargzProc->arguments().join(" ").latin1()); |
1162 | break; | 1161 | break; |
1163 | case SendBuffer: | 1162 | case SendBuffer: |
1164 | if ( !buf.open( IO_ReadOnly) ) { | 1163 | if ( !buf.open( IO_ReadOnly) ) { |
1165 | emit failed(); | 1164 | emit failed(); |
1166 | mode = Idle; | 1165 | mode = Idle; |
1167 | return; | 1166 | return; |
1168 | } | 1167 | } |
1169 | 1168 | ||
1170 | // odebug << "Debug: Sending byte array" << oendl; | 1169 | // odebug << "Debug: Sending byte array" << oendl; |
1171 | bytes_written = 0; | 1170 | bytes_written = 0; |
1172 | while( !buf.atEnd() ) | 1171 | while( !buf.atEnd() ) |
1173 | putch( buf.getch() ); | 1172 | putch( buf.getch() ); |
1174 | buf.close(); | 1173 | buf.close(); |
1175 | break; | 1174 | break; |
1176 | case RetrieveFile: | 1175 | case RetrieveFile: |
1177 | // retrieve file mode | 1176 | // retrieve file mode |
1178 | if ( file.exists() && !file.remove() ) { | 1177 | if ( file.exists() && !file.remove() ) { |
1179 | emit failed(); | 1178 | emit failed(); |
1180 | mode = Idle; | 1179 | mode = Idle; |
1181 | return; | 1180 | return; |
1182 | } | 1181 | } |
1183 | 1182 | ||
1184 | if ( !file.open( IO_WriteOnly) ) { | 1183 | if ( !file.open( IO_WriteOnly) ) { |
1185 | emit failed(); | 1184 | emit failed(); |
1186 | mode = Idle; | 1185 | mode = Idle; |
1187 | return; | 1186 | return; |
1188 | } | 1187 | } |
1189 | // odebug << "Debug: Retrieving file " << file.name() << "" << oendl; | 1188 | // odebug << "Debug: Retrieving file " << file.name() << "" << oendl; |
1190 | break; | 1189 | break; |
1191 | case RetrieveGzipFile: | 1190 | case RetrieveGzipFile: |
1192 | odebug << "=-> starting tar process to receive .tgz file" << oendl; | 1191 | odebug << "=-> starting tar process to receive .tgz file" << oendl; |
1193 | break; | 1192 | break; |
1194 | case RetrieveBuffer: | 1193 | case RetrieveBuffer: |
1195 | // retrieve buffer mode | 1194 | // retrieve buffer mode |
1196 | if ( !buf.open( IO_WriteOnly) ) { | 1195 | if ( !buf.open( IO_WriteOnly) ) { |
1197 | emit failed(); | 1196 | emit failed(); |
1198 | mode = Idle; | 1197 | mode = Idle; |
1199 | return; | 1198 | return; |
1200 | } | 1199 | } |
1201 | // odebug << "Debug: Retrieving byte array" << oendl; | 1200 | // odebug << "Debug: Retrieving byte array" << oendl; |
1202 | break; | 1201 | break; |
1203 | case Idle: | 1202 | case Idle: |
1204 | odebug << "connection established but mode set to Idle; BUG!" << oendl; | 1203 | odebug << "connection established but mode set to Idle; BUG!" << oendl; |
1205 | break; | 1204 | break; |
1206 | } | 1205 | } |
1207 | } | 1206 | } |
1208 | 1207 | ||
1209 | void ServerDTP::connectionClosed() | 1208 | void ServerDTP::connectionClosed() |
1210 | { | 1209 | { |
1211 | //odebug << "Debug: Data connection closed " << bytes_written << " bytes written" << oendl; | 1210 | //odebug << "Debug: Data connection closed " << bytes_written << " bytes written" << oendl; |
1212 | 1211 | ||
1213 | // send file mode | 1212 | // send file mode |
1214 | if ( SendFile == mode ) { | 1213 | if ( SendFile == mode ) { |
1215 | if ( bytes_written == file.size() ) | 1214 | if ( bytes_written == file.size() ) |
1216 | emit completed(); | 1215 | emit completed(); |
1217 | else | 1216 | else |
1218 | emit failed(); | 1217 | emit failed(); |
1219 | } | 1218 | } |
1220 | 1219 | ||
1221 | // send buffer mode | 1220 | // send buffer mode |
1222 | else if ( SendBuffer == mode ) { | 1221 | else if ( SendBuffer == mode ) { |
1223 | if ( bytes_written == buf.size() ) | 1222 | if ( bytes_written == buf.size() ) |
1224 | emit completed(); | 1223 | emit completed(); |
1225 | else | 1224 | else |
1226 | emit failed(); | 1225 | emit failed(); |
1227 | } | 1226 | } |
1228 | 1227 | ||
1229 | // retrieve file mode | 1228 | // retrieve file mode |
1230 | else if ( RetrieveFile == mode ) { | 1229 | else if ( RetrieveFile == mode ) { |
1231 | file.close(); | 1230 | file.close(); |
1232 | if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { | 1231 | if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { |
1233 | odebug << "STOR incomplete" << oendl; | 1232 | odebug << "STOR incomplete" << oendl; |
1234 | file.remove(); | 1233 | file.remove(); |
1235 | emit failed(); | 1234 | emit failed(); |
1236 | } else { | 1235 | } else { |
1237 | emit completed(); | 1236 | emit completed(); |
1238 | } | 1237 | } |
1239 | } | 1238 | } |
1240 | 1239 | ||
1241 | else if ( RetrieveGzipFile == mode ) { | 1240 | else if ( RetrieveGzipFile == mode ) { |
1242 | odebug << "Done writing ungzip file; closing input" << oendl; | 1241 | odebug << "Done writing ungzip file; closing input" << oendl; |
1243 | retrieveTargzProc->flushStdin(); | 1242 | retrieveTargzProc->flushStdin(); |
1244 | retrieveTargzProc->closeStdin(); | 1243 | retrieveTargzProc->closeStdin(); |
1245 | } | 1244 | } |
1246 | 1245 | ||
1247 | // retrieve buffer mode | 1246 | // retrieve buffer mode |
1248 | else if ( RetrieveBuffer == mode ) { | 1247 | else if ( RetrieveBuffer == mode ) { |
1249 | buf.close(); | 1248 | buf.close(); |
1250 | emit completed(); | 1249 | emit completed(); |
1251 | } | 1250 | } |
1252 | 1251 | ||
1253 | mode = Idle; | 1252 | mode = Idle; |
1254 | } | 1253 | } |
1255 | 1254 | ||
1256 | void ServerDTP::bytesWritten( int bytes ) | 1255 | void ServerDTP::bytesWritten( int bytes ) |
1257 | { | 1256 | { |
1258 | bytes_written += bytes; | 1257 | bytes_written += bytes; |
1259 | 1258 | ||
1260 | // send file mode | 1259 | // send file mode |
1261 | if ( SendFile == mode ) { | 1260 | if ( SendFile == mode ) { |
1262 | 1261 | ||
1263 | if ( bytes_written == file.size() ) { | 1262 | if ( bytes_written == file.size() ) { |
1264 | // odebug << "Debug: Sending complete: " << file.size() << " bytes" << oendl; | 1263 | // odebug << "Debug: Sending complete: " << file.size() << " bytes" << oendl; |
1265 | file.close(); | 1264 | file.close(); |
1266 | emit completed(); | 1265 | emit completed(); |
1267 | mode = Idle; | 1266 | mode = Idle; |
1268 | } | 1267 | } |
1269 | else if( !file.atEnd() ) { | 1268 | else if( !file.atEnd() ) { |
1270 | QCString s; | 1269 | QCString s; |
1271 | s.resize( block_size ); | 1270 | s.resize( block_size ); |
1272 | int bytes = file.readBlock( s.data(), block_size ); | 1271 | int bytes = file.readBlock( s.data(), block_size ); |
1273 | writeBlock( s.data(), bytes ); | 1272 | writeBlock( s.data(), bytes ); |
1274 | } | 1273 | } |
1275 | } | 1274 | } |
1276 | 1275 | ||
1277 | // send buffer mode | 1276 | // send buffer mode |
1278 | if ( SendBuffer == mode ) { | 1277 | if ( SendBuffer == mode ) { |
1279 | 1278 | ||
1280 | if ( bytes_written == buf.size() ) { | 1279 | if ( bytes_written == buf.size() ) { |
1281 | // odebug << "Debug: Sending complete: " << buf.size() << " bytes" << oendl; | 1280 | // odebug << "Debug: Sending complete: " << buf.size() << " bytes" << oendl; |
1282 | emit completed(); | 1281 | emit completed(); |
1283 | mode = Idle; | 1282 | mode = Idle; |
1284 | } | 1283 | } |
1285 | } | 1284 | } |
1286 | } | 1285 | } |
1287 | 1286 | ||
1288 | void ServerDTP::readyRead() | 1287 | void ServerDTP::readyRead() |
1289 | { | 1288 | { |
1290 | // retrieve file mode | 1289 | // retrieve file mode |
1291 | if ( RetrieveFile == mode ) { | 1290 | if ( RetrieveFile == mode ) { |
1292 | QCString s; | 1291 | QCString s; |
1293 | s.resize( bytesAvailable() ); | 1292 | s.resize( bytesAvailable() ); |
1294 | readBlock( s.data(), bytesAvailable() ); | 1293 | readBlock( s.data(), bytesAvailable() ); |
1295 | file.writeBlock( s.data(), s.size() ); | 1294 | file.writeBlock( s.data(), s.size() ); |
1296 | } | 1295 | } |
1297 | else if ( RetrieveGzipFile == mode ) { | 1296 | else if ( RetrieveGzipFile == mode ) { |
1298 | if ( !retrieveTargzProc->isRunning() ) | 1297 | if ( !retrieveTargzProc->isRunning() ) |
1299 | retrieveTargzProc->start(); | 1298 | retrieveTargzProc->start(); |
1300 | 1299 | ||
1301 | QByteArray s; | 1300 | QByteArray s; |
1302 | s.resize( bytesAvailable() ); | 1301 | s.resize( bytesAvailable() ); |
1303 | readBlock( s.data(), bytesAvailable() ); | 1302 | readBlock( s.data(), bytesAvailable() ); |
1304 | retrieveTargzProc->writeToStdin( s ); | 1303 | retrieveTargzProc->writeToStdin( s ); |
1305 | odebug << "wrote " << s.size() << " bytes to ungzip " << oendl; | 1304 | odebug << "wrote " << s.size() << " bytes to ungzip " << oendl; |
1306 | } | 1305 | } |
1307 | // retrieve buffer mode | 1306 | // retrieve buffer mode |
1308 | else if ( RetrieveBuffer == mode ) { | 1307 | else if ( RetrieveBuffer == mode ) { |
1309 | QCString s; | 1308 | QCString s; |
1310 | s.resize( bytesAvailable() ); | 1309 | s.resize( bytesAvailable() ); |
1311 | readBlock( s.data(), bytesAvailable() ); | 1310 | readBlock( s.data(), bytesAvailable() ); |
1312 | buf.writeBlock( s.data(), s.size() ); | 1311 | buf.writeBlock( s.data(), s.size() ); |
1313 | } | 1312 | } |
1314 | } | 1313 | } |
1315 | 1314 | ||
1316 | void ServerDTP::writeTargzBlock() | 1315 | void ServerDTP::writeTargzBlock() |
1317 | { | 1316 | { |
1318 | QByteArray block = createTargzProc->readStdout(); | 1317 | QByteArray block = createTargzProc->readStdout(); |
1319 | writeBlock( block.data(), block.size() ); | 1318 | writeBlock( block.data(), block.size() ); |
1320 | odebug << "writeTargzBlock " << block.size() << "" << oendl; | 1319 | odebug << "writeTargzBlock " << block.size() << "" << oendl; |
1321 | } | 1320 | } |
1322 | 1321 | ||
1323 | void ServerDTP::targzDone() | 1322 | void ServerDTP::targzDone() |
1324 | { | 1323 | { |
1325 | odebug << "tar and gzip done" << oendl; | 1324 | odebug << "tar and gzip done" << oendl; |
1326 | emit completed(); | 1325 | emit completed(); |
1327 | mode = Idle; | 1326 | mode = Idle; |
1328 | disconnect( createTargzProc, SIGNAL( readyReadStdout() ), | 1327 | disconnect( createTargzProc, SIGNAL( readyReadStdout() ), |
1329 | this, SLOT( writeTargzBlock() ) ); | 1328 | this, SLOT( writeTargzBlock() ) ); |
1330 | } | 1329 | } |
1331 | 1330 | ||
1332 | void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) | 1331 | void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) |
1333 | { | 1332 | { |
1334 | file.setName( fn ); | 1333 | file.setName( fn ); |
1335 | mode = SendFile; | 1334 | mode = SendFile; |
1336 | connectToHost( host.toString(), port ); | 1335 | connectToHost( host.toString(), port ); |
1337 | } | 1336 | } |
1338 | 1337 | ||
1339 | void ServerDTP::sendFile( const QString fn ) | 1338 | void ServerDTP::sendFile( const QString fn ) |
1340 | { | 1339 | { |
1341 | file.setName( fn ); | 1340 | file.setName( fn ); |
1342 | mode = SendFile; | 1341 | mode = SendFile; |
1343 | } | 1342 | } |
1344 | 1343 | ||
1345 | void ServerDTP::sendGzipFile( const QString &fn, | 1344 | void ServerDTP::sendGzipFile( const QString &fn, |
1346 | const QStringList &archiveTargets, | 1345 | const QStringList &archiveTargets, |
1347 | const QHostAddress& host, Q_UINT16 port ) | 1346 | const QHostAddress& host, Q_UINT16 port ) |
1348 | { | 1347 | { |
1349 | sendGzipFile( fn, archiveTargets ); | 1348 | sendGzipFile( fn, archiveTargets ); |
1350 | connectToHost( host.toString(), port ); | 1349 | connectToHost( host.toString(), port ); |
1351 | } | 1350 | } |
1352 | 1351 | ||
1353 | void ServerDTP::sendGzipFile( const QString &fn, | 1352 | void ServerDTP::sendGzipFile( const QString &fn, |
1354 | const QStringList &archiveTargets ) | 1353 | const QStringList &archiveTargets ) |
1355 | { | 1354 | { |
1356 | mode = SendGzipFile; | 1355 | mode = SendGzipFile; |
1357 | file.setName( fn ); | 1356 | file.setName( fn ); |
1358 | 1357 | ||
1359 | QStringList args = "targzip"; | 1358 | QStringList args = "targzip"; |
1360 | //args += "-cv"; | 1359 | //args += "-cv"; |
1361 | args += archiveTargets; | 1360 | args += archiveTargets; |
1362 | odebug << "sendGzipFile " << args.join(" ") << "" << oendl; | 1361 | odebug << "sendGzipFile " << args.join(" ") << "" << oendl; |
1363 | createTargzProc->setArguments( args ); | 1362 | createTargzProc->setArguments( args ); |
1364 | connect( createTargzProc, | 1363 | connect( createTargzProc, |
1365 | SIGNAL( readyReadStdout() ), SLOT( writeTargzBlock() ) ); | 1364 | SIGNAL( readyReadStdout() ), SLOT( writeTargzBlock() ) ); |
1366 | } | 1365 | } |
1367 | 1366 | ||
1368 | void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port, int fileSize ) | 1367 | void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port, int fileSize ) |
1369 | { | 1368 | { |
1370 | recvFileSize = fileSize; | 1369 | recvFileSize = fileSize; |
1371 | file.setName( fn ); | 1370 | file.setName( fn ); |
1372 | mode = RetrieveFile; | 1371 | mode = RetrieveFile; |
1373 | connectToHost( host.toString(), port ); | 1372 | connectToHost( host.toString(), port ); |
1374 | } | 1373 | } |
1375 | 1374 | ||
1376 | void ServerDTP::retrieveFile( const QString fn, int fileSize ) | 1375 | void ServerDTP::retrieveFile( const QString fn, int fileSize ) |
1377 | { | 1376 | { |
1378 | recvFileSize = fileSize; | 1377 | recvFileSize = fileSize; |
1379 | file.setName( fn ); | 1378 | file.setName( fn ); |
1380 | mode = RetrieveFile; | 1379 | mode = RetrieveFile; |
1381 | } | 1380 | } |
1382 | 1381 | ||
1383 | void ServerDTP::retrieveGzipFile( const QString &fn ) | 1382 | void ServerDTP::retrieveGzipFile( const QString &fn ) |
1384 | { | 1383 | { |
1385 | odebug << "retrieveGzipFile " << fn << "" << oendl; | 1384 | odebug << "retrieveGzipFile " << fn << "" << oendl; |
1386 | file.setName( fn ); | 1385 | file.setName( fn ); |
1387 | mode = RetrieveGzipFile; | 1386 | mode = RetrieveGzipFile; |
1388 | 1387 | ||
1389 | retrieveTargzProc->setArguments( "targunzip" ); | 1388 | retrieveTargzProc->setArguments( "targunzip" ); |
1390 | connect( retrieveTargzProc, SIGNAL( processExited() ), | 1389 | connect( retrieveTargzProc, SIGNAL( processExited() ), |
1391 | SLOT( extractTarDone() ) ); | 1390 | SLOT( extractTarDone() ) ); |
1392 | } | 1391 | } |
1393 | 1392 | ||
1394 | void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port ) | 1393 | void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port ) |
1395 | { | 1394 | { |
1396 | retrieveGzipFile( fn ); | 1395 | retrieveGzipFile( fn ); |
1397 | connectToHost( host.toString(), port ); | 1396 | connectToHost( host.toString(), port ); |
1398 | } | 1397 | } |
1399 | 1398 | ||
1400 | void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port ) | 1399 | void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port ) |
1401 | { | 1400 | { |
1402 | buf.setBuffer( array ); | 1401 | buf.setBuffer( array ); |
1403 | mode = SendBuffer; | 1402 | mode = SendBuffer; |
1404 | connectToHost( host.toString(), port ); | 1403 | connectToHost( host.toString(), port ); |
1405 | } | 1404 | } |
1406 | 1405 | ||
1407 | void ServerDTP::sendByteArray( const QByteArray& array ) | 1406 | void ServerDTP::sendByteArray( const QByteArray& array ) |
1408 | { | 1407 | { |
1409 | buf.setBuffer( array ); | 1408 | buf.setBuffer( array ); |
1410 | mode = SendBuffer; | 1409 | mode = SendBuffer; |
1411 | } | 1410 | } |
1412 | 1411 | ||
1413 | void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port ) | 1412 | void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port ) |
1414 | { | 1413 | { |
1415 | buf.setBuffer( QByteArray() ); | 1414 | buf.setBuffer( QByteArray() ); |
1416 | mode = RetrieveBuffer; | 1415 | mode = RetrieveBuffer; |
1417 | connectToHost( host.toString(), port ); | 1416 | connectToHost( host.toString(), port ); |
1418 | } | 1417 | } |
1419 | 1418 | ||
1420 | void ServerDTP::retrieveByteArray() | 1419 | void ServerDTP::retrieveByteArray() |
1421 | { | 1420 | { |
1422 | buf.setBuffer( QByteArray() ); | 1421 | buf.setBuffer( QByteArray() ); |
1423 | mode = RetrieveBuffer; | 1422 | mode = RetrieveBuffer; |
1424 | } | 1423 | } |
1425 | 1424 | ||
1426 | void ServerDTP::setSocket( int socket ) | 1425 | void ServerDTP::setSocket( int socket ) |
1427 | { | 1426 | { |
1428 | QSocket::setSocket( socket ); | 1427 | QSocket::setSocket( socket ); |
1429 | connected(); | 1428 | connected(); |
1430 | } | 1429 | } |
1431 | 1430 | ||