summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/documentlist.cpp8
-rw-r--r--core/launcher/qprocess_unix.cpp646
-rw-r--r--core/launcher/screensaver.cpp386
-rw-r--r--core/launcher/server.cpp434
-rw-r--r--core/launcher/transferserver.cpp851
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
@@ -358,103 +358,103 @@ void DocumentList::DiffAppLnks()
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}
417void DocumentList::storageChanged() 417void 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
436void DocumentList::sendAllDocLinks() 436void 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();
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
@@ -104,1070 +104,1070 @@ public:
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*/
128class QProc 128class QProc
129{ 129{
130public: 130public:
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 **********************************************************************/
176class QProcessManager : public QObject 176class QProcessManager : public QObject
177{ 177{
178 Q_OBJECT 178 Q_OBJECT
179 179
180public: 180public:
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
189public slots: 189public slots:
190 void removeMe(); 190 void removeMe();
191 void sigchldHnd( int ); 191 void sigchldHnd( int );
192 192
193public: 193public:
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
200QCleanupHandler<QProcessManager> qprocess_cleanup_procmanager; 200QCleanupHandler<QProcessManager> qprocess_cleanup_procmanager;
201 201
202QProcessManager::QProcessManager() 202QProcessManager::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
257QProcessManager::~QProcessManager() 257QProcessManager::~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
280void QProcessManager::append( QProc *p ) 280void 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
288void QProcessManager::remove( QProc *p ) 288void 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
297void QProcessManager::cleanup() 297void 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
304void QProcessManager::removeMe() 304void 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
313void QProcessManager::sigchldHnd( int fd ) 313void 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 **********************************************************************/
383QProcessManager *QProcessPrivate::procManager = 0; 383QProcessManager *QProcessPrivate::procManager = 0;
384 384
385QProcessPrivate::QProcessPrivate() 385QProcessPrivate::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
402QProcessPrivate::~QProcessPrivate() 402QProcessPrivate::~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*/
429void QProcessPrivate::closeOpenSocketsForChild() 429void 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
447void QProcessPrivate::newProc( pid_t pid, QProcess *process ) 447void 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 **********************************************************************/
463QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS ) 463QT_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}
473QT_SIGNAL_RETTYPE qt_C_sigpipeHnd( QT_SIGNAL_ARGS ) 473QT_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*/
487void QProcess::init() 487void 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*/
498void QProcess::reset() 498void 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
508QByteArray* QProcess::bufStdout() 508QByteArray* 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
518QByteArray* QProcess::bufStderr() 518QByteArray* 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
528void QProcess::consumeBufStdout( int consume ) 528void 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
540void QProcess::consumeBufStderr( int consume ) 540void 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*/
563QProcess::~QProcess() 563QProcess::~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*/
598bool QProcess::start( QStringList *env ) 598bool 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
799error: 799error:
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*/
835void QProcess::tryTerminate() const 835void 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*/
865void QProcess::kill() const 865void 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*/
876bool QProcess::isRunning() const 876bool 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*/
919void QProcess::writeToStdin( const QByteArray& buf ) 919void 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*/
938void QProcess::closeStdin() 938void 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*/
963void QProcess::socketRead( int fd ) 963void 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*/
1054void QProcess::socketWrite( int fd ) 1054void 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*/
1086void QProcess::flushStdin() 1086void 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*/
1095void QProcess::timeout() 1095void 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*/
1104void QProcess::setIoRedirection( bool value ) 1104void 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*/
1125void QProcess::setNotifyOnExit( bool value ) 1125void 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*/
1134void QProcess::setWroteStdinConnected( bool value ) 1134void 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*/
1152QProcess::PID QProcess::processIdentifier() 1152QProcess::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
1159int QProcess::priority() const 1159int 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
1166void QProcess::setPriority(int p) 1166void 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
10using namespace Opie::Core; 11using namespace Opie::Core;
11 12
12 13
13 14
14OpieScreenSaver::OpieScreenSaver ( ) 15OpieScreenSaver::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 */
51void OpieScreenSaver::restore() 52void 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 */
71bool OpieScreenSaver::save( int level ) 72bool 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 */
135void OpieScreenSaver::setIntervals ( int dim, int lightoff, int suspend ) 136void 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 */
181void OpieScreenSaver::setInterval ( int interval ) 182void OpieScreenSaver::setInterval ( int interval )
182{ 183{
183 setIntervals ( -1, -1, interval ); 184 setIntervals ( -1, -1, interval );
184} 185}
185 186
186 187
187void OpieScreenSaver::setMode ( int mode ) 188void 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 */
204void OpieScreenSaver::setBacklight ( int bright ) 205void 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 */
251void OpieScreenSaver::setBacklightInternal ( int bright ) 253void 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 */
279void OpieScreenSaver::timerEvent ( QTimerEvent * ) 281void 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 */
306void OpieScreenSaver::setDisplayState ( bool on ) 310void 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 */
318void OpieScreenSaver::powerStatusChanged ( PowerStatus ps ) 322void 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
@@ -49,681 +49,681 @@
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>
52using namespace Opie::Core; 52using 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
66extern QRect qt_maxWindowRect; 66extern QRect qt_maxWindowRect;
67 67
68static QWidget *calibrate(bool) 68static 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
100static Global::Command builtins[] = { 100static 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
126Server::Server() : 126Server::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
181void Server::show() 181void Server::show()
182{ 182{
183 ServerApplication::login(TRUE); 183 ServerApplication::login(TRUE);
184 QWidget::show(); 184 QWidget::show();
185} 185}
186 186
187Server::~Server() 187Server::~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
199static bool hasVisibleWindow(const QString& clientname, bool partial) 199static 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
224void Server::activate(const ODeviceButton* button, bool held) 224void 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
260typedef struct KeyOverride { 260typedef struct KeyOverride {
261 ushort scan_code; 261 ushort scan_code;
262 QWSServer::KeyMap map; 262 QWSServer::KeyMap map;
263}; 263};
264 264
265 265
266static const KeyOverride jp109keys[] = { 266static 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
289bool Server::setKeyboardLayout( const QString &kb ) 289bool 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
311void Server::systemMsg(const QCString &msg, const QByteArray &data) 311void 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
527void Server::receiveTaskBar(const QCString &msg, const QByteArray &data) 527void 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
550void Server::cancelSync() 550void 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
559bool Server::mkdir(const QString &localPath) 559bool 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
604void Server::styleChange( QStyle &s ) 604void Server::styleChange( QStyle &s )
605{ 605{
606 QWidget::styleChange( s ); 606 QWidget::styleChange( s );
607} 607}
608 608
609void Server::startTransferServer() 609void 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
637void Server::timerEvent( QTimerEvent *e ) 637void 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
663void Server::terminateServers() 663void 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
671void Server::syncConnectionClosed( const QHostAddress & ) 671void 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
678void Server::pokeTimeMonitors() 678void 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
691void Server::applicationLaunched(int, const QString &app) 691void Server::applicationLaunched(int, const QString &app)
692{ 692{
693 serverGui->applicationStateChanged( app, ServerInterface::Launching ); 693 serverGui->applicationStateChanged( app, ServerInterface::Launching );
694} 694}
695 695
696void Server::applicationTerminated(int pid, const QString &app) 696void 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
704void Server::applicationConnected(const QString &app) 704void Server::applicationConnected(const QString &app)
705{ 705{
706 serverGui->applicationStateChanged( app, ServerInterface::Running ); 706 serverGui->applicationStateChanged( app, ServerInterface::Running );
707} 707}
708 708
709void Server::storageChanged() 709void 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
718void Server::preloadApps() 718void 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
@@ -33,1391 +33,1390 @@ 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
50const int block_size = 51200; 50const int block_size = 51200;
51 51
52TransferServer::TransferServer( Q_UINT16 port, QObject *parent, 52TransferServer::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
61void TransferServer::authorizeConnections() 61void 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
73void TransferServer::closed(ServerPI *item) 73void TransferServer::closed(ServerPI *item)
74{ 74{
75 connections.removeRef(item); 75 connections.removeRef(item);
76} 76}
77 77
78TransferServer::~TransferServer() 78TransferServer::~TransferServer()
79{ 79{
80} 80}
81 81
82void TransferServer::newConnection( int socket ) 82void 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
89QString SyncAuthentication::serverId() 89QString 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
102QString SyncAuthentication::ownerName() 102QString 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
115QString SyncAuthentication::loginName() 115QString 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
127int SyncAuthentication::isAuthorized(QHostAddress peeraddress) 127int 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
144bool SyncAuthentication::checkUser( const QString& user ) 144bool 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
151bool SyncAuthentication::checkPassword( const QString& password ) 151bool 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
295ServerPI::ServerPI( int socket, QObject *parent, const char* name ) 295ServerPI::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
342ServerPI::~ServerPI() 342ServerPI::~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
352bool ServerPI::verifyAuthorised() 352bool 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
361void ServerPI::connectionClosed() 361void 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
367void ServerPI::send( const QString& msg ) 367void 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
374void ServerPI::read() 374void ServerPI::read()
375{ 375{
376 while ( canReadLine() ) 376 while ( canReadLine() )
377 process( readLine().stripWhiteSpace() ); 377 process( readLine().stripWhiteSpace() );
378} 378}
379 379
380bool ServerPI::checkReadFile( const QString& file ) 380bool 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
393bool ServerPI::checkWriteFile( const QString& file ) 393bool 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
410void ServerPI::process( const QString& message ) 410void 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
772bool ServerPI::backupRestoreGzip( const QString &file ) 772bool 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
778bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets ) 778bool 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
791void ServerPI::sendFile( const QString& file ) 790void 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
807void ServerPI::retrieveFile( const QString& file ) 806void 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
824bool ServerPI::parsePort( const QString& pp ) 823bool 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
836void ServerPI::dtpCompleted() 835void 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
851void ServerPI::dtpFailed() 850void 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
859void ServerPI::dtpError( int ) 858void 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
867bool ServerPI::sendList( const QString& arg ) 866bool 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
928QString ServerPI::fileListing( QFileInfo *info ) 927QString 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
984QString ServerPI::permissionString( QFileInfo *info ) 983QString 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
1016void ServerPI::newConnection( int socket ) 1015void 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
1054QString ServerPI::absFilePath( const QString& file ) 1053QString 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
1066void ServerPI::timerEvent( QTimerEvent * ) 1065void ServerPI::timerEvent( QTimerEvent * )
1067{ 1066{
1068 connectionClosed(); 1067 connectionClosed();
1069} 1068}
1070 1069
1071 1070
1072ServerDTP::ServerDTP( QObject *parent, const char* name) 1071ServerDTP::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
1096ServerDTP::~ServerDTP() 1095ServerDTP::~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
1112void ServerDTP::extractTarDone() 1111void 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
1121void ServerDTP::connected() 1120void 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
1209void ServerDTP::connectionClosed() 1208void 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
1256void ServerDTP::bytesWritten( int bytes ) 1255void 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
1288void ServerDTP::readyRead() 1287void 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
1316void ServerDTP::writeTargzBlock() 1315void 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
1323void ServerDTP::targzDone() 1322void 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
1332void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) 1331void 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
1339void ServerDTP::sendFile( const QString fn ) 1338void 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
1345void ServerDTP::sendGzipFile( const QString &fn, 1344void 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
1353void ServerDTP::sendGzipFile( const QString &fn, 1352void 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
1368void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port, int fileSize ) 1367void 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
1376void ServerDTP::retrieveFile( const QString fn, int fileSize ) 1375void 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
1383void ServerDTP::retrieveGzipFile( const QString &fn ) 1382void 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
1394void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port ) 1393void 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
1400void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port ) 1399void 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
1407void ServerDTP::sendByteArray( const QByteArray& array ) 1406void 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
1413void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port ) 1412void 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
1420void ServerDTP::retrieveByteArray() 1419void ServerDTP::retrieveByteArray()
1421{ 1420{
1422 buf.setBuffer( QByteArray() ); 1421 buf.setBuffer( QByteArray() );
1423 mode = RetrieveBuffer; 1422 mode = RetrieveBuffer;