summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/launcher/launcher.pro2
-rw-r--r--core/launcher/qprocess.cpp654
-rw-r--r--core/launcher/qprocess.h174
-rw-r--r--core/launcher/qprocess_unix.cpp1158
-rw-r--r--core/launcher/transferserver.cpp191
-rw-r--r--core/launcher/transferserver.h14
6 files changed, 120 insertions, 2073 deletions
diff --git a/core/launcher/launcher.pro b/core/launcher/launcher.pro
index 3391378..21f8374 100644
--- a/core/launcher/launcher.pro
+++ b/core/launcher/launcher.pro
@@ -1,13 +1,12 @@
1 TEMPLATE= app 1 TEMPLATE= app
2 CONFIG = qt warn_on release 2 CONFIG = qt warn_on release
3 DESTDIR = ../../bin 3 DESTDIR = ../../bin
4 HEADERS = background.h \ 4 HEADERS = background.h \
5 desktop.h \ 5 desktop.h \
6 screensaver.h \ 6 screensaver.h \
7 qprocess.h \
8 mediummountgui.h \ 7 mediummountgui.h \
9 info.h \ 8 info.h \
10 appicons.h \ 9 appicons.h \
11 taskbar.h \ 10 taskbar.h \
12 sidething.h \ 11 sidething.h \
13 runningappbar.h \ 12 runningappbar.h \
@@ -44,13 +43,12 @@ HEADERS = background.h \
44 ../../rsync/qrsync.h \ 43 ../../rsync/qrsync.h \
45 quicklauncher.h 44 quicklauncher.h
46 SOURCES = background.cpp \ 45 SOURCES = background.cpp \
47 desktop.cpp \ 46 desktop.cpp \
48 screensaver.cpp \ 47 screensaver.cpp \
49 mediummountgui.cpp \ 48 mediummountgui.cpp \
50 qprocess.cpp qprocess_unix.cpp \
51 info.cpp \ 49 info.cpp \
52 appicons.cpp \ 50 appicons.cpp \
53 taskbar.cpp \ 51 taskbar.cpp \
54 sidething.cpp \ 52 sidething.cpp \
55 runningappbar.cpp \ 53 runningappbar.cpp \
56 stabmon.cpp \ 54 stabmon.cpp \
diff --git a/core/launcher/qprocess.cpp b/core/launcher/qprocess.cpp
deleted file mode 100644
index 618c0e0..0000000
--- a/core/launcher/qprocess.cpp
+++ b/dev/null
@@ -1,654 +0,0 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QProcess class
5**
6** Created : 20000905
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include <stdio.h>
39#include <stdlib.h>
40
41#include "qprocess.h"
42
43#ifndef QT_NO_PROCESS
44
45#include "qapplication.h"
46
47
48//#define QT_QPROCESS_DEBUG
49
50
51/*!
52 \class QProcess qprocess.h
53
54 \brief The QProcess class is used to start external programs and to
55 communicate with them.
56
57 This is a temporary class. This will be replaced by Qt 3's QProcess class.
58*/
59
60/*!
61 \enum QProcess::Communication
62
63 This enum type defines the communication channels connected to the
64 process.
65
66 \value Stdin Data can be written to the process's standard input.
67
68 \value Stdout Data can be read from the process's standard output.
69
70 \value Stderr Data can be read from the process's standard error.
71
72 \value DupStderr Duplicates standard error to standard output for new
73 processes; i.e. everything that the process writes to standard error, is
74 reported by QProcess on standard output instead. This is especially useful if
75 your application requires that the output on standard output and standard
76 error is read in the same order as the process output it. Please note that
77 this is a binary flag, so if you want to activate this together with standard
78 input, output and error redirection (the default), you have to specify
79 \c{Stdin|Stdout|Stderr|DupStderr} for the setCommunication() call.
80
81 \sa setCommunication() communication()
82*/
83
84/*!
85 Constructs a QProcess object. The \a parent and \a name parameters are passed
86 to the QObject constructor.
87
88 \sa setArguments() addArgument() start()
89*/
90QProcess::QProcess( QObject *parent, const char *name )
91 : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
92 wroteToStdinConnected( FALSE ),
93 readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
94 comms( Stdin|Stdout|Stderr )
95{
96 init();
97}
98
99/*!
100 Constructs a QProcess with \a arg0 as the command to be executed. The
101 \a parent and \a name parameters are passed to the QObject constructor.
102
103 The process is not started. You must call start() or launch()
104 to start the process.
105
106 \sa setArguments() addArgument() start()
107*/
108QProcess::QProcess( const QString& arg0, QObject *parent, const char *name )
109 : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
110 wroteToStdinConnected( FALSE ),
111 readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
112 comms( Stdin|Stdout|Stderr )
113{
114 init();
115 addArgument( arg0 );
116}
117
118/*!
119 Constructs a QProcess with \a args as the arguments of the process. The first
120 element in the list is the command to be executed. The other elements in the
121 list are the arguments to this command. The \a parent and \a name
122 parameters are passed to the QObject constructor.
123
124 The process is not started. You must call start() or launch()
125 to start the process.
126
127 \sa setArguments() addArgument() start()
128*/
129QProcess::QProcess( const QStringList& args, QObject *parent, const char *name )
130 : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
131 wroteToStdinConnected( FALSE ),
132 readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
133 comms( Stdin|Stdout|Stderr )
134{
135 init();
136 setArguments( args );
137}
138
139
140/*!
141 Returns the list of arguments that are set for the process. Arguments can be
142 specified with the constructor or with the functions setArguments() and
143 addArgument().
144
145 \sa setArguments() addArgument()
146*/
147QStringList QProcess::arguments() const
148{
149 return _arguments;
150}
151
152/*!
153 Clears the list of arguments that are set for the process.
154
155 \sa setArguments() addArgument()
156*/
157void QProcess::clearArguments()
158{
159 _arguments.clear();
160}
161
162/*!
163 Sets \a args as the arguments for the process. The first element in the list
164 is the command to be executed. The other elements in the list are the
165 arguments to the command. Any previous arguments are deleted.
166
167 \sa arguments() addArgument()
168*/
169void QProcess::setArguments( const QStringList& args )
170{
171 _arguments = args;
172}
173
174/*!
175 Adds \a arg to the end of the list of arguments.
176
177 The first element in the list of arguments is the command to be
178 executed; the following elements are the arguments to the command.
179
180 \sa arguments() setArguments()
181*/
182void QProcess::addArgument( const QString& arg )
183{
184 _arguments.append( arg );
185}
186
187#ifndef QT_NO_DIR
188/*!
189 Returns the working directory that was set with
190 setWorkingDirectory(), or the current directory if none has been
191 set.
192
193 \sa setWorkingDirectory() QDir::current()
194*/
195QDir QProcess::workingDirectory() const
196{
197 return workingDir;
198}
199
200/*!
201 Sets \a dir as the working directory for a process. This does not affect
202 running processes; only processes that are started afterwards are affected.
203
204 Setting the working directory is especially useful for processes that try to
205 access files with relative filenames.
206
207 \sa workingDirectory() start()
208*/
209void QProcess::setWorkingDirectory( const QDir& dir )
210{
211 workingDir = dir;
212}
213#endif //QT_NO_DIR
214
215/*!
216 Returns the communication required with the process.
217
218 \sa setCommunication()
219*/
220int QProcess::communication() const
221{
222 return comms;
223}
224
225/*!
226 Sets \a commFlags as the communication required with the process.
227
228 \a commFlags is a bitwise OR between the flags defined in \c Communication.
229
230 The default is \c{Stdin|Stdout|Stderr}.
231
232 \sa communication()
233*/
234void QProcess::setCommunication( int commFlags )
235{
236 comms = commFlags;
237}
238
239/*!
240 Returns TRUE if the process has exited normally; otherwise returns
241 FALSE. This implies that this function returns FALSE if the process
242 is still running.
243
244 \sa isRunning() exitStatus() processExited()
245*/
246bool QProcess::normalExit() const
247{
248 // isRunning() has the side effect that it determines the exit status!
249 if ( isRunning() )
250 return FALSE;
251 else
252 return exitNormal;
253}
254
255/*!
256 Returns the exit status of the process or 0 if the process is still
257 running. This function returns immediately and does not wait until
258 the process is finished.
259
260 If normalExit() is FALSE (e.g. if the program was killed or
261 crashed), this function returns 0, so you should check the return
262 value of normalExit() before relying on this value.
263
264 \sa normalExit() processExited()
265*/
266int QProcess::exitStatus() const
267{
268 // isRunning() has the side effect that it determines the exit status!
269 if ( isRunning() )
270 return 0;
271 else
272 return exitStat;
273}
274
275
276/*!
277 Reads the data that the process has written to standard output. When
278 new data is written to standard output, the class emits the signal
279 readyReadStdout().
280
281 If there is no data to read, this function returns a QByteArray of
282 size 0: it does not wait until there is something to read.
283
284 \sa readyReadStdout() readLineStdout() readStderr() writeToStdin()
285*/
286QByteArray QProcess::readStdout()
287{
288 if ( readStdoutCalled ) {
289 return QByteArray();
290 }
291 readStdoutCalled = TRUE;
292
293 QByteArray buf = bufStdout()->copy();
294 consumeBufStdout( -1 ); // consume everything
295
296 readStdoutCalled = FALSE;
297 return buf;
298}
299
300/*!
301 Reads the data that the process has written to standard error. When
302 new data is written to standard error, the class emits the signal
303 readyReadStderr().
304
305 If there is no data to read, this function returns a QByteArray of
306 size 0: it does not wait until there is something to read.
307
308 \sa readyReadStderr() readLineStderr() readStdout() writeToStdin()
309*/
310QByteArray QProcess::readStderr()
311{
312 if ( readStderrCalled ) {
313 return QByteArray();
314 }
315 readStderrCalled = TRUE;
316
317 QByteArray buf = bufStderr()->copy();
318 consumeBufStderr( -1 ); // consume everything
319
320 readStderrCalled = FALSE;
321 return buf;
322}
323
324/*!
325 Returns TRUE if it's possible to read an entire line of text from
326 standard output at this time; otherwise returns FALSE.
327
328 \sa readLineStdout() canReadLineStderr()
329*/
330bool QProcess::canReadLineStdout() const
331{
332 QProcess *that = (QProcess*)this;
333 return that->scanNewline( TRUE, 0 );
334}
335
336/*!
337 Returns TRUE if it's possible to read an entire line of text from
338 standard error at this time; otherwise returns FALSE.
339
340 \sa readLineStderr() canReadLineStdout()
341*/
342bool QProcess::canReadLineStderr() const
343{
344 QProcess *that = (QProcess*)this;
345 return that->scanNewline( FALSE, 0 );
346}
347
348/*!
349 Reads a line of text from standard output, excluding any trailing newline or
350 carriage return characters, and returns it. Returns QString::null if
351 canReadLineStdout() returns FALSE.
352
353 \sa canReadLineStdout() readyReadStdout() readStdout() readLineStderr()
354*/
355QString QProcess::readLineStdout()
356{
357 QByteArray a;
358 QString s;
359 if ( scanNewline( TRUE, &a ) ) {
360 if ( a.isEmpty() )
361 s = "";
362 else
363 s = QString( a );
364 }
365 return s;
366}
367
368/*!
369 Reads a line of text from standard error, excluding any trailing newline or
370 carriage return characters and returns it. Returns QString::null if
371 canReadLineStderr() returns FALSE.
372
373 \sa canReadLineStderr() readyReadStderr() readStderr() readLineStdout()
374*/
375QString QProcess::readLineStderr()
376{
377 QByteArray a;
378 QString s;
379 if ( scanNewline( FALSE, &a ) ) {
380 if ( a.isEmpty() )
381 s = "";
382 else
383 s = QString( a );
384 }
385 return s;
386}
387
388/*!
389 This private function scans for any occurrence of \n or \r\n in the
390 buffer \e buf. It stores the text in the byte array \a store if it is
391 non-null.
392*/
393bool QProcess::scanNewline( bool stdOut, QByteArray *store )
394{
395 QByteArray *buf;
396 if ( stdOut )
397 buf = bufStdout();
398 else
399 buf = bufStderr();
400 uint n = buf->size();
401 uint i;
402 for ( i=0; i<n; i++ ) {
403 if ( buf->at(i) == '\n' ) {
404 break;
405 }
406 }
407 if ( i >= n )
408 return FALSE;
409
410 if ( store ) {
411 uint lineLength = i;
412 if ( lineLength>0 && buf->at(lineLength-1) == '\r' )
413 lineLength--; // (if there are two \r, let one stay)
414 store->resize( lineLength );
415 memcpy( store->data(), buf->data(), lineLength );
416 if ( stdOut )
417 consumeBufStdout( i+1 );
418 else
419 consumeBufStderr( i+1 );
420 }
421 return TRUE;
422}
423
424/*!
425 \fn void QProcess::launchFinished()
426
427 This signal is emitted when the process was started with launch().
428 If the start was successful, this signal is emitted after all the
429 data has been written to standard input. If the start failed, then
430 this signal is emitted immediately.
431
432 \sa launch() QObject::deleteLater()
433*/
434
435/*!
436 Runs the process and writes the data \a buf to the process's standard input.
437 If all the data is written to standard input, standard input is
438 closed. The command is searched for in the path for executable programs;
439 you can also use an absolute path in the command itself.
440
441 If \a env is null, then the process is started with the same environment as
442 the starting process. If \a env is non-null, then the values in the
443 stringlist are interpreted as environment setttings of the form \c
444 {key=value} and the process is started with these environment settings. For
445 convenience, there is a small exception to this rule under Unix: if \a env
446 does not contain any settings for the environment variable \c
447 LD_LIBRARY_PATH, then this variable is inherited from the starting process.
448
449 Returns TRUE if the process could be started; otherwise returns FALSE.
450
451 Note that you should not use the slots writeToStdin() and closeStdin() on
452 processes started with launch(), since the result is not well-defined. If you
453 need these slots, use start() instead.
454
455 The process may or may not read the \a buf data sent to its standard
456 input.
457
458 You can call this function even when a process that was started with
459 this instance is still running. Be aware that if you do this the
460 standard input of the process that was launched first will be
461 closed, with any pending data being deleted, and the process will be
462 left to run out of your control. Similarly, if the process could not
463 be started the standard input will be closed and the pending data
464 deleted. (On operating systems that have zombie processes, Qt will
465 also wait() on the old process.)
466
467 The object emits the signal launchFinished() when this function
468 call is finished. If the start was successful, this signal is
469 emitted after all the data has been written to standard input. If
470 the start failed, then this signal is emitted immediately.
471
472 \sa start() launchFinished();
473*/
474bool QProcess::launch( const QByteArray& buf, QStringList *env )
475{
476 if ( start( env ) ) {
477 if ( !buf.isEmpty() ) {
478 connect( this, SIGNAL(wroteToStdin()),
479 this, SLOT(closeStdinLaunch()) );
480 writeToStdin( buf );
481 } else {
482 closeStdin();
483 emit launchFinished();
484 }
485 return TRUE;
486 } else {
487 emit launchFinished();
488 return FALSE;
489 }
490}
491
492/*! \overload
493
494 The data \a buf is written to standard input with writeToStdin()
495 using the QString::local8Bit() representation of the strings.
496*/
497bool QProcess::launch( const QString& buf, QStringList *env )
498{
499 if ( start( env ) ) {
500 if ( !buf.isEmpty() ) {
501 connect( this, SIGNAL(wroteToStdin()),
502 this, SLOT(closeStdinLaunch()) );
503 writeToStdin( buf );
504 } else {
505 closeStdin();
506 emit launchFinished();
507 }
508 return TRUE;
509 } else {
510 emit launchFinished();
511 return FALSE;
512 }
513}
514
515/*!
516 This private slot is used by the launch() functions to close standard input.
517*/
518void QProcess::closeStdinLaunch()
519{
520 disconnect( this, SIGNAL(wroteToStdin()),
521 this, SLOT(closeStdinLaunch()) );
522 closeStdin();
523 emit launchFinished();
524}
525
526
527/*!
528 \fn void QProcess::readyReadStdout()
529
530 This signal is emitted when the process has written data to standard output.
531 You can read the data with readStdout().
532
533 Note that this signal is only emitted when there is new data and not
534 when there is old, but unread data. In the slot connected to this signal, you
535 should always read everything that is available at that moment to make sure
536 that you don't lose any data.
537
538 \sa readStdout() readLineStdout() readyReadStderr()
539*/
540/*!
541 \fn void QProcess::readyReadStderr()
542
543 This signal is emitted when the process has written data to standard error.
544 You can read the data with readStderr().
545
546 Note that this signal is only emitted when there is new data and not
547 when there is old, but unread data. In the slot connected to this signal, you
548 should always read everything that is available at that moment to make sure
549 that you don't lose any data.
550
551 \sa readStderr() readLineStderr() readyReadStdout()
552*/
553/*!
554 \fn void QProcess::processExited()
555
556 This signal is emitted when the process has exited.
557
558 \sa isRunning() normalExit() exitStatus() start() launch()
559*/
560/*!
561 \fn void QProcess::wroteToStdin()
562
563 This signal is emitted if the data sent to standard input (via
564 writeToStdin()) was actually written to the process. This does not
565 imply that the process really read the data, since this class only detects
566 when it was able to write the data to the operating system. But it is now
567 safe to close standard input without losing pending data.
568
569 \sa writeToStdin() closeStdin()
570*/
571
572
573/*! \overload
574
575 The string \a buf is handled as text using
576 the QString::local8Bit() representation.
577*/
578void QProcess::writeToStdin( const QString& buf )
579{
580 QByteArray tmp = buf.local8Bit();
581 tmp.resize( buf.length() );
582 writeToStdin( tmp );
583}
584
585
586/*
587 * Under Windows the implementation is not so nice: it is not that easy to
588 * detect when one of the signals should be emitted; therefore there are some
589 * timers that query the information.
590 * To keep it a little efficient, use the timers only when they are needed.
591 * They are needed, if you are interested in the signals. So use
592 * connectNotify() and disconnectNotify() to keep track of your interest.
593 */
594/*! \reimp
595*/
596void QProcess::connectNotify( const char * signal )
597{
598#if defined(QT_QPROCESS_DEBUG)
599 qDebug( "QProcess::connectNotify(): signal %s has been connected", signal );
600#endif
601 if ( !ioRedirection )
602 if ( qstrcmp( signal, SIGNAL(readyReadStdout()) )==0 ||
603 qstrcmp( signal, SIGNAL(readyReadStderr()) )==0
604 ) {
605#if defined(QT_QPROCESS_DEBUG)
606 qDebug( "QProcess::connectNotify(): set ioRedirection to TRUE" );
607#endif
608 setIoRedirection( TRUE );
609 return;
610 }
611 if ( !notifyOnExit && qstrcmp( signal, SIGNAL(processExited()) )==0 ) {
612#if defined(QT_QPROCESS_DEBUG)
613 qDebug( "QProcess::connectNotify(): set notifyOnExit to TRUE" );
614#endif
615 setNotifyOnExit( TRUE );
616 return;
617 }
618 if ( !wroteToStdinConnected && qstrcmp( signal, SIGNAL(wroteToStdin()) )==0 ) {
619#if defined(QT_QPROCESS_DEBUG)
620 qDebug( "QProcess::connectNotify(): set wroteToStdinConnected to TRUE" );
621#endif
622 setWroteStdinConnected( TRUE );
623 return;
624 }
625}
626
627/*! \reimp
628*/
629void QProcess::disconnectNotify( const char * )
630{
631 if ( ioRedirection &&
632 receivers( SIGNAL(readyReadStdout()) ) ==0 &&
633 receivers( SIGNAL(readyReadStderr()) ) ==0
634 ) {
635#if defined(QT_QPROCESS_DEBUG)
636 qDebug( "QProcess::disconnectNotify(): set ioRedirection to FALSE" );
637#endif
638 setIoRedirection( FALSE );
639 }
640 if ( notifyOnExit && receivers( SIGNAL(processExited()) ) == 0 ) {
641#if defined(QT_QPROCESS_DEBUG)
642 qDebug( "QProcess::disconnectNotify(): set notifyOnExit to FALSE" );
643#endif
644 setNotifyOnExit( FALSE );
645 }
646 if ( wroteToStdinConnected && receivers( SIGNAL(wroteToStdin()) ) == 0 ) {
647#if defined(QT_QPROCESS_DEBUG)
648 qDebug( "QProcess::disconnectNotify(): set wroteToStdinConnected to FALSE" );
649#endif
650 setWroteStdinConnected( FALSE );
651 }
652}
653
654#endif // QT_NO_PROCESS
diff --git a/core/launcher/qprocess.h b/core/launcher/qprocess.h
deleted file mode 100644
index 306e659..0000000
--- a/core/launcher/qprocess.h
+++ b/dev/null
@@ -1,174 +0,0 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QProcess class
5**
6** Created : 20000905
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#ifndef QPROCESS_H
39#define QPROCESS_H
40
41#ifndef QT_H
42#include "qobject.h"
43#include "qstringlist.h"
44#include "qdir.h"
45#endif // QT_H
46
47#ifndef QT_NO_PROCESS
48
49class QProcessPrivate;
50
51
52class Q_EXPORT QProcess : public QObject
53{
54 Q_OBJECT
55public:
56 QProcess( QObject *parent=0, const char *name=0 );
57 QProcess( const QString& arg0, QObject *parent=0, const char *name=0 );
58 QProcess( const QStringList& args, QObject *parent=0, const char *name=0 );
59 ~QProcess();
60
61 // set and get the arguments and working directory
62 QStringList arguments() const;
63 void clearArguments();
64 virtual void setArguments( const QStringList& args );
65 virtual void addArgument( const QString& arg );
66#ifndef QT_NO_DIR
67 QDir workingDirectory() const;
68 virtual void setWorkingDirectory( const QDir& dir );
69#endif
70
71 // set and get the comms wanted
72 enum Communication { Stdin=0x01, Stdout=0x02, Stderr=0x04, DupStderr=0x08 };
73 void setCommunication( int c );
74 int communication() const;
75
76 // start the execution
77 virtual bool start( QStringList *env=0 );
78 virtual bool launch( const QString& buf, QStringList *env=0 );
79 virtual bool launch( const QByteArray& buf, QStringList *env=0 );
80
81 // inquire the status
82 bool isRunning() const;
83 bool normalExit() const;
84 int exitStatus() const;
85
86 // reading
87 virtual QByteArray readStdout();
88 virtual QByteArray readStderr();
89 bool canReadLineStdout() const;
90 bool canReadLineStderr() const;
91 virtual QString readLineStdout();
92 virtual QString readLineStderr();
93
94 // get platform dependent process information
95#if defined(Q_OS_WIN32)
96 typedef void* PID;
97#else
98 typedef long Q_LONG;
99 typedef Q_LONG PID;
100#endif
101 PID processIdentifier();
102
103 void flushStdin();
104
105signals:
106 void readyReadStdout();
107 void readyReadStderr();
108 void processExited();
109 void wroteToStdin();
110 void launchFinished();
111
112public slots:
113 // end the execution
114 void tryTerminate() const;
115 void kill() const;
116
117 // input
118 virtual void writeToStdin( const QByteArray& buf );
119 virtual void writeToStdin( const QString& buf );
120 virtual void closeStdin();
121
122protected: // ### or private?
123 void connectNotify( const char * signal );
124 void disconnectNotify( const char * signal );
125private:
126 void setIoRedirection( bool value );
127 void setNotifyOnExit( bool value );
128 void setWroteStdinConnected( bool value );
129
130 void init();
131 void reset();
132#if defined(Q_OS_WIN32)
133 uint readStddev( HANDLE dev, char *buf, uint bytes );
134#endif
135 bool scanNewline( bool stdOut, QByteArray *store );
136
137 QByteArray* bufStdout();
138 QByteArray* bufStderr();
139 void consumeBufStdout( int consume );
140 void consumeBufStderr( int consume );
141
142private slots:
143 void socketRead( int fd );
144 void socketWrite( int fd );
145 void timeout();
146 void closeStdinLaunch();
147
148private:
149 QProcessPrivate *d;
150#ifndef QT_NO_DIR
151 QDir workingDir;
152#endif
153 QStringList _arguments;
154
155 int exitStat; // exit status
156 bool exitNormal; // normal exit?
157 bool ioRedirection; // automatically set be (dis)connectNotify
158 bool notifyOnExit; // automatically set be (dis)connectNotify
159 bool wroteToStdinConnected; // automatically set be (dis)connectNotify
160
161 bool readStdoutCalled;
162 bool readStderrCalled;
163 int comms;
164
165 friend class QProcessPrivate;
166#if defined(Q_OS_UNIX) || defined(_OS_UNIX) || defined(UNIX)
167 friend class QProcessManager;
168 friend class QProc;
169#endif
170};
171
172#endif // QT_NO_PROCESS
173
174#endif // QPROCESS_H
diff --git a/core/launcher/qprocess_unix.cpp b/core/launcher/qprocess_unix.cpp
deleted file mode 100644
index 75f0f0c..0000000
--- a/core/launcher/qprocess_unix.cpp
+++ b/dev/null
@@ -1,1158 +0,0 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QProcess class for Unix
5**
6** Created : 20000905
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38//#include "qplatformdefs.h"
39
40// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
41#if defined(connect)
42#undef connect
43#endif
44
45#include "qprocess.h"
46
47#ifndef QT_NO_PROCESS
48
49#include "qapplication.h"
50#include "qqueue.h"
51#include "qlist.h"
52#include "qsocketnotifier.h"
53#include "qtimer.h"
54#include "qregexp.h"
55
56#include "qcleanuphandler_p.h"
57
58#include <stdlib.h>
59
60// ### FOR Qt 2.3 compat
61#include <unistd.h>
62#include <signal.h>
63#include <sys/socket.h>
64#include <sys/ioctl.h>
65#include <sys/wait.h>
66#include <sys/fcntl.h>
67
68#include <errno.h>
69
70#ifdef __MIPSEL__
71# ifndef SOCK_DGRAM
72# define SOCK_DGRAM 1
73# endif
74# ifndef SOCK_STREAM
75# define SOCK_STREAM 2
76# endif
77#endif
78
79//#define QT_QPROCESS_DEBUG
80
81
82#ifdef Q_C_CALLBACKS
83extern "C" {
84#endif // Q_C_CALLBACKS
85
86#define QT_SIGNAL_RETTYPE void
87#define QT_SIGNAL_ARGS int
88#define QT_SIGNAL_IGNORE SIG_IGN
89
90 QT_SIGNAL_RETTYPE qt_C_sigchldHnd(QT_SIGNAL_ARGS);
91
92#ifdef Q_C_CALLBACKS
93}
94#endif // Q_C_CALLBACKS
95
96
97class QProc;
98class QProcessManager;
99class QProcessPrivate
100{
101public:
102 QProcessPrivate();
103 ~QProcessPrivate();
104
105 void closeOpenSocketsForChild();
106 void newProc( pid_t pid, QProcess *process );
107
108 QByteArray bufStdout;
109 QByteArray bufStderr;
110
111 QQueue<QByteArray> stdinBuf;
112
113 QSocketNotifier *notifierStdin;
114 QSocketNotifier *notifierStdout;
115 QSocketNotifier *notifierStderr;
116
117 ssize_t stdinBufRead;
118 QProc *proc;
119
120 bool exitValuesCalculated;
121 bool socketReadCalled;
122
123 static QProcessManager *procManager;
124};
125
126
127/***********************************************************************
128 *
129 * QProc
130 *
131 **********************************************************************/
132/*
133 The class QProcess does not necessarily map exactly to the running
134 child processes: if the process is finished, the QProcess class may still be
135 there; furthermore a user can use QProcess to start more than one process.
136
137 The helper-class QProc has the semantics that one instance of this class maps
138 directly to a running child process.
139*/
140class QProc
141{
142public:
143 QProc( pid_t p, QProcess *proc=0 ) : pid(p), process(proc)
144 {
145#if defined(QT_QPROCESS_DEBUG)
146 qDebug( "QProc: Constructor for pid %d and QProcess %p", pid, process );
147#endif
148 socketStdin = 0;
149 socketStdout = 0;
150 socketStderr = 0;
151 }
152 ~QProc()
153 {
154#if defined(QT_QPROCESS_DEBUG)
155 qDebug( "QProc: Destructor for pid %d and QProcess %p", pid, process );
156#endif
157 if ( process != 0 ) {
158 if ( process->d->notifierStdin )
159 process->d->notifierStdin->setEnabled( FALSE );
160 if ( process->d->notifierStdout )
161 process->d->notifierStdout->setEnabled( FALSE );
162 if ( process->d->notifierStderr )
163 process->d->notifierStderr->setEnabled( FALSE );
164 process->d->proc = 0;
165 }
166 if( socketStdin != 0 )
167 ::close( socketStdin );
168 // ### close these sockets even on parent exit or is it better only on
169 // sigchld (but what do I have to do with them on exit then)?
170 if( socketStdout != 0 )
171 ::close( socketStdout );
172 if( socketStderr != 0 )
173 ::close( socketStderr );
174 }
175
176 pid_t pid;
177 int socketStdin;
178 int socketStdout;
179 int socketStderr;
180 QProcess *process;
181};
182
183/***********************************************************************
184 *
185 * QProcessManager
186 *
187 **********************************************************************/
188class QProcessManager : public QObject
189{
190 Q_OBJECT
191
192public:
193 QProcessManager();
194 ~QProcessManager();
195
196 void append( QProc *p );
197 void remove( QProc *p );
198
199 void cleanup();
200
201public slots:
202 void removeMe();
203 void sigchldHnd( int );
204
205public:
206 struct sigaction oldactChld;
207 struct sigaction oldactPipe;
208 QList<QProc> *procList;
209 int sigchldFd[2];
210};
211
212QCleanupHandler<QProcessManager> qprocess_cleanup_procmanager;
213
214QProcessManager::QProcessManager()
215{
216 procList = new QList<QProc>;
217 procList->setAutoDelete( TRUE );
218
219 // The SIGCHLD handler writes to a socket to tell the manager that
220 // something happened. This is done to get the processing in sync with the
221 // event reporting.
222 if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) {
223 sigchldFd[0] = 0;
224 sigchldFd[1] = 0;
225 } else {
226#if defined(QT_QPROCESS_DEBUG)
227 qDebug( "QProcessManager: install socket notifier (%d)", sigchldFd[1] );
228#endif
229 QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1],
230 QSocketNotifier::Read, this );
231 connect( sn, SIGNAL(activated(int)),
232 this, SLOT(sigchldHnd(int)) );
233 sn->setEnabled( TRUE );
234 }
235
236 // install a SIGCHLD handler and ignore SIGPIPE
237 struct sigaction act;
238
239#if defined(QT_QPROCESS_DEBUG)
240 qDebug( "QProcessManager: install a SIGCHLD handler" );
241#endif
242 act.sa_handler = qt_C_sigchldHnd;
243 sigemptyset( &(act.sa_mask) );
244 sigaddset( &(act.sa_mask), SIGCHLD );
245 act.sa_flags = SA_NOCLDSTOP;
246#if defined(SA_RESTART)
247 act.sa_flags |= SA_RESTART;
248#endif
249 if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 )
250 qWarning( "Error installing SIGCHLD handler" );
251
252#if defined(QT_QPROCESS_DEBUG)
253 qDebug( "QProcessManager: install a SIGPIPE handler (SIG_IGN)" );
254#endif
255 act.sa_handler = QT_SIGNAL_IGNORE;
256 sigemptyset( &(act.sa_mask) );
257 sigaddset( &(act.sa_mask), SIGPIPE );
258 act.sa_flags = 0;
259 if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 )
260 qWarning( "Error installing SIGPIPE handler" );
261}
262
263QProcessManager::~QProcessManager()
264{
265 delete procList;
266
267 if ( sigchldFd[0] != 0 )
268 ::close( sigchldFd[0] );
269 if ( sigchldFd[1] != 0 )
270 ::close( sigchldFd[1] );
271
272 // restore SIGCHLD handler
273#if defined(QT_QPROCESS_DEBUG)
274 qDebug( "QProcessManager: restore old sigchild handler" );
275#endif
276 if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 )
277 qWarning( "Error restoring SIGCHLD handler" );
278
279#if defined(QT_QPROCESS_DEBUG)
280 qDebug( "QProcessManager: restore old sigpipe handler" );
281#endif
282 if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 )
283 qWarning( "Error restoring SIGPIPE handler" );
284}
285
286void QProcessManager::append( QProc *p )
287{
288 procList->append( p );
289#if defined(QT_QPROCESS_DEBUG)
290 qDebug( "QProcessManager: append process (procList.count(): %d)", procList->count() );
291#endif
292}
293
294void QProcessManager::remove( QProc *p )
295{
296 procList->remove( p );
297#if defined(QT_QPROCESS_DEBUG)
298 qDebug( "QProcessManager: remove process (procList.count(): %d)", procList->count() );
299#endif
300 cleanup();
301}
302
303void QProcessManager::cleanup()
304{
305 if ( procList->count() == 0 ) {
306 QTimer::singleShot( 0, this, SLOT(removeMe()) );
307 }
308}
309
310void QProcessManager::removeMe()
311{
312 if ( procList->count() == 0 ) {
313 qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager );
314 QProcessPrivate::procManager = 0;
315 delete this;
316 }
317}
318
319void QProcessManager::sigchldHnd( int fd )
320{
321 char tmp;
322 ::read( fd, &tmp, sizeof(tmp) );
323#if defined(QT_QPROCESS_DEBUG)
324 qDebug( "QProcessManager::sigchldHnd()" );
325#endif
326 QProc *proc;
327 QProcess *process;
328 bool removeProc;
329 proc = procList->first();
330 while ( proc != 0 ) {
331 removeProc = FALSE;
332 process = proc->process;
333 if ( process != 0 ) {
334 if ( !process->isRunning() ) {
335#if defined(QT_QPROCESS_DEBUG)
336 qDebug( "QProcessManager::sigchldHnd() (PID: %d): process exited (QProcess available)", proc->pid );
337#endif
338 // read pending data
339 int nbytes = 0;
340 if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) {
341#if defined(QT_QPROCESS_DEBUG)
342 qDebug( "QProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stdout", proc->pid, nbytes );
343#endif
344 process->socketRead( proc->socketStdout );
345 }
346 nbytes = 0;
347 if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) {
348#if defined(QT_QPROCESS_DEBUG)
349 qDebug( "QProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stderr", proc->pid, nbytes );
350#endif
351 process->socketRead( proc->socketStderr );
352 }
353
354 if ( process->notifyOnExit )
355 emit process->processExited();
356
357 removeProc = TRUE;
358 }
359 } else {
360 int status;
361 if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) {
362#if defined(QT_QPROCESS_DEBUG)
363 qDebug( "QProcessManager::sigchldHnd() (PID: %d): process exited (QProcess not available)", proc->pid );
364#endif
365 removeProc = TRUE;
366 }
367 }
368 if ( removeProc ) {
369 QProc *oldproc = proc;
370 proc = procList->next();
371 remove( oldproc );
372 } else {
373 proc = procList->next();
374 }
375 }
376}
377
378#include "qprocess_unix.moc"
379
380
381/***********************************************************************
382 *
383 * QProcessPrivate
384 *
385 **********************************************************************/
386QProcessManager *QProcessPrivate::procManager = 0;
387
388QProcessPrivate::QProcessPrivate()
389{
390#if defined(QT_QPROCESS_DEBUG)
391 qDebug( "QProcessPrivate: Constructor" );
392#endif
393 stdinBufRead = 0;
394
395 notifierStdin = 0;
396 notifierStdout = 0;
397 notifierStderr = 0;
398
399 exitValuesCalculated = FALSE;
400 socketReadCalled = FALSE;
401
402 proc = 0;
403}
404
405QProcessPrivate::~QProcessPrivate()
406{
407#if defined(QT_QPROCESS_DEBUG)
408 qDebug( "QProcessPrivate: Destructor" );
409#endif
410
411 if ( proc != 0 ) {
412 if ( proc->socketStdin != 0 ) {
413 ::close( proc->socketStdin );
414 proc->socketStdin = 0;
415 }
416 proc->process = 0;
417 }
418
419 while ( !stdinBuf.isEmpty() ) {
420 delete stdinBuf.dequeue();
421 }
422 delete notifierStdin;
423 delete notifierStdout;
424 delete notifierStderr;
425}
426
427/*
428 Closes all open sockets in the child process that are not needed by the child
429 process. Otherwise one child may have an open socket on standard input, etc.
430 of another child.
431*/
432void QProcessPrivate::closeOpenSocketsForChild()
433{
434 if ( procManager != 0 ) {
435 if ( procManager->sigchldFd[0] != 0 )
436 ::close( procManager->sigchldFd[0] );
437 if ( procManager->sigchldFd[1] != 0 )
438 ::close( procManager->sigchldFd[1] );
439
440 // close also the sockets from other QProcess instances
441 QProc *proc;
442 for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) {
443 ::close( proc->socketStdin );
444 ::close( proc->socketStdout );
445 ::close( proc->socketStderr );
446 }
447 }
448}
449
450void QProcessPrivate::newProc( pid_t pid, QProcess *process )
451{
452 proc = new QProc( pid, process );
453 if ( procManager == 0 ) {
454 procManager = new QProcessManager;
455 qprocess_cleanup_procmanager.add( &procManager );
456 }
457 // the QProcessManager takes care of deleting the QProc instances
458 procManager->append( proc );
459}
460
461/***********************************************************************
462 *
463 * sigchld handler callback
464 *
465 **********************************************************************/
466QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS )
467{
468 if ( QProcessPrivate::procManager == 0 )
469 return;
470 if ( QProcessPrivate::procManager->sigchldFd[0] == 0 )
471 return;
472
473 char a = 1;
474 ::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) );
475}
476
477
478/***********************************************************************
479 *
480 * QProcess
481 *
482 **********************************************************************/
483/*!
484 This private class does basic initialization.
485*/
486void QProcess::init()
487{
488 d = new QProcessPrivate();
489 exitStat = 0;
490 exitNormal = FALSE;
491}
492
493/*!
494 This private class resets the process variables, etc. so that it can be used
495 for another process to start.
496*/
497void QProcess::reset()
498{
499 delete d;
500 d = new QProcessPrivate();
501 exitStat = 0;
502 exitNormal = FALSE;
503 d->bufStdout.resize( 0 );
504 d->bufStderr.resize( 0 );
505}
506
507QByteArray* QProcess::bufStdout()
508{
509 if ( d->proc && d->proc->socketStdout ) {
510 // ### can this cause a blocking behaviour (maybe do a ioctl() to see
511 // if data is available)?
512 socketRead( d->proc->socketStdout );
513 }
514 return &d->bufStdout;
515}
516
517QByteArray* QProcess::bufStderr()
518{
519 if ( d->proc && d->proc->socketStderr ) {
520 // ### can this cause a blocking behaviour (maybe do a ioctl() to see
521 // if data is available)?
522 socketRead( d->proc->socketStderr );
523 }
524 return &d->bufStderr;
525}
526
527void QProcess::consumeBufStdout( int consume )
528{
529 uint n = d->bufStdout.size();
530 if ( consume==-1 || (uint)consume >= n ) {
531 d->bufStdout.resize( 0 );
532 } else {
533 QByteArray tmp( n - consume );
534 memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume );
535 d->bufStdout = tmp;
536 }
537}
538
539void QProcess::consumeBufStderr( int consume )
540{
541 uint n = d->bufStderr.size();
542 if ( consume==-1 || (uint)consume >= n ) {
543 d->bufStderr.resize( 0 );
544 } else {
545 QByteArray tmp( n - consume );
546 memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume );
547 d->bufStderr = tmp;
548 }
549}
550
551/*!
552 Destroys the class.
553
554 If the process is running, it is NOT terminated! Standard input, standard
555 output and standard error of the process are closed.
556
557 You can connect the destroyed() signal to the kill() slot, if you want the
558 process to be terminated automatically when the class is destroyed.
559
560 \sa tryTerminate() kill()
561*/
562QProcess::~QProcess()
563{
564 delete d;
565}
566
567/*!
568 Tries to run a process for the command and arguments that were specified with
569 setArguments(), addArgument() or that were specified in the constructor. The
570 command is searched in the path for executable programs; you can also use an
571 absolute path to the command.
572
573 If \a env is null, then the process is started with the same environment as
574 the starting process. If \a env is non-null, then the values in the
575 stringlist are interpreted as environment setttings of the form \c
576 {key=value} and the process is started in these environment settings. For
577 convenience, there is a small exception to this rule: under Unix, if \a env
578 does not contain any settings for the environment variable \c
579 LD_LIBRARY_PATH, then this variable is inherited from the starting process;
580 under Windows the same applies for the enverionment varialbe \c PATH.
581
582 Returns TRUE if the process could be started, otherwise FALSE.
583
584 You can write data to standard input of the process with
585 writeToStdin(), you can close standard input with closeStdin() and you can
586 terminate the process tryTerminate() resp. kill().
587
588 You can call this function even when there already is a running
589 process in this object. In this case, QProcess closes standard input
590 of the old process and deletes pending data, i.e., you loose all
591 control over that process, but the process is not terminated. This applies
592 also if the process could not be started. (On operating systems that have
593 zombie processes, Qt will also wait() on the old process.)
594
595 \sa launch() closeStdin()
596*/
597bool QProcess::start( QStringList *env )
598{
599#if defined(QT_QPROCESS_DEBUG)
600 qDebug( "QProcess::start()" );
601#endif
602 reset();
603
604 int sStdin[2];
605 int sStdout[2];
606 int sStderr[2];
607
608 // open sockets for piping
609 if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) {
610 return FALSE;
611 }
612 if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) {
613 return FALSE;
614 }
615 if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) {
616 return FALSE;
617 }
618
619 // the following pipe is only used to determine if the process could be
620 // started
621 int fd[2];
622 if ( pipe( fd ) < 0 ) {
623 // non critical error, go on
624 fd[0] = 0;
625 fd[1] = 0;
626 }
627
628 // construct the arguments for exec
629 QCString *arglistQ = new QCString[ _arguments.count() + 1 ];
630 const char** arglist = new const char*[ _arguments.count() + 1 ];
631 int i = 0;
632 for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) {
633 arglistQ[i] = (*it).local8Bit();
634 arglist[i] = arglistQ[i];
635#if defined(QT_QPROCESS_DEBUG)
636 qDebug( "QProcess::start(): arg %d = %s", i, arglist[i] );
637#endif
638 i++;
639 }
640 arglist[i] = 0;
641
642 // Must make sure signal handlers are installed before exec'ing
643 // in case the process exits quickly.
644 if ( d->procManager == 0 ) {
645 d->procManager = new QProcessManager;
646 qprocess_cleanup_procmanager.add( &d->procManager );
647 }
648
649 // fork and exec
650 QApplication::flushX();
651 pid_t pid = fork();
652 if ( pid == 0 ) {
653 // child
654 d->closeOpenSocketsForChild();
655 if ( comms & Stdin ) {
656 ::close( sStdin[1] );
657 ::dup2( sStdin[0], STDIN_FILENO );
658 }
659 if ( comms & Stdout ) {
660 ::close( sStdout[0] );
661 ::dup2( sStdout[1], STDOUT_FILENO );
662 }
663 if ( comms & Stderr ) {
664 ::close( sStderr[0] );
665 ::dup2( sStderr[1], STDERR_FILENO );
666 }
667 if ( comms & DupStderr ) {
668 ::dup2( STDOUT_FILENO, STDERR_FILENO );
669 }
670#ifndef QT_NO_DIR
671 ::chdir( workingDir.absPath().latin1() );
672#endif
673 if ( fd[0] )
674 ::close( fd[0] );
675 if ( fd[1] )
676 ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess
677
678 if ( env == 0 ) { // inherit environment and start process
679 ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice
680 } else { // start process with environment settins as specified in env
681 // construct the environment for exec
682 int numEntries = env->count();
683 bool setLibraryPath =
684 env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() &&
685 getenv( "LD_LIBRARY_PATH" ) != 0;
686 if ( setLibraryPath )
687 numEntries++;
688 QCString *envlistQ = new QCString[ numEntries + 1 ];
689 const char** envlist = new const char*[ numEntries + 1 ];
690 int i = 0;
691 if ( setLibraryPath ) {
692 envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit();
693 envlist[i] = envlistQ[i];
694 i++;
695 }
696 for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) {
697 envlistQ[i] = (*it).local8Bit();
698 envlist[i] = envlistQ[i];
699 i++;
700 }
701 envlist[i] = 0;
702
703 // look for the executable in the search path
704 if ( _arguments.count()>0 && getenv("PATH")!=0 ) {
705 QString command = _arguments[0];
706 if ( !command.contains( '/' ) ) {
707 QStringList pathList = QStringList::split( ':', getenv( "PATH" ) );
708 for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) {
709 QString dir = *it;
710#ifdef Q_OS_MACX
711 if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle
712 dir += "/" + command + ".app/Contents/MacOS";
713#endif
714#ifndef QT_NO_DIR
715 QFileInfo fileInfo( dir, command );
716#else
717 QFileInfo fileInfo( dir + "/" + command );
718#endif
719 if ( fileInfo.isExecutable() ) {
720 arglistQ[0] = fileInfo.filePath().local8Bit();
721 arglist[0] = arglistQ[0];
722 break;
723 }
724 }
725 }
726 }
727 ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice
728 }
729 if ( fd[1] ) {
730 char buf = 0;
731 ::write( fd[1], &buf, 1 );
732 ::close( fd[1] );
733 }
734 ::exit( -1 );
735 } else if ( pid == -1 ) {
736 // error forking
737 goto error;
738 }
739
740 // test if exec was successful
741 if ( fd[1] )
742 ::close( fd[1] );
743 if ( fd[0] ) {
744 char buf;
745 for ( ;; ) {
746 int n = ::read( fd[0], &buf, 1 );
747 if ( n==1 ) {
748 // socket was not closed => error
749 d->proc = 0;
750 goto error;
751 } else if ( n==-1 ) {
752 if ( errno==EAGAIN || errno==EINTR )
753 // try it again
754 continue;
755 }
756 break;
757 }
758 ::close( fd[0] );
759 }
760
761 d->newProc( pid, this );
762
763 if ( comms & Stdin ) {
764 ::close( sStdin[0] );
765 d->proc->socketStdin = sStdin[1];
766 d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write );
767 connect( d->notifierStdin, SIGNAL(activated(int)),
768 this, SLOT(socketWrite(int)) );
769 // setup notifiers for the sockets
770 if ( !d->stdinBuf.isEmpty() ) {
771 d->notifierStdin->setEnabled( TRUE );
772 }
773 }
774 if ( comms & Stdout ) {
775 ::close( sStdout[1] );
776 d->proc->socketStdout = sStdout[0];
777 d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read );
778 connect( d->notifierStdout, SIGNAL(activated(int)),
779 this, SLOT(socketRead(int)) );
780 if ( ioRedirection )
781 d->notifierStdout->setEnabled( TRUE );
782 }
783 if ( comms & Stderr ) {
784 ::close( sStderr[1] );
785 d->proc->socketStderr = sStderr[0];
786 d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read );
787 connect( d->notifierStderr, SIGNAL(activated(int)),
788 this, SLOT(socketRead(int)) );
789 if ( ioRedirection )
790 d->notifierStderr->setEnabled( TRUE );
791 }
792
793 // cleanup and return
794 delete[] arglistQ;
795 delete[] arglist;
796 return TRUE;
797
798error:
799#if defined(QT_QPROCESS_DEBUG)
800 qDebug( "QProcess::start(): error starting process" );
801#endif
802 if ( d->procManager )
803 d->procManager->cleanup();
804 if ( comms & Stdin ) {
805 ::close( sStdin[1] );
806 ::close( sStdin[0] );
807 }
808 if ( comms & Stdout ) {
809 ::close( sStdout[0] );
810 ::close( sStdout[1] );
811 }
812 if ( comms & Stderr ) {
813 ::close( sStderr[0] );
814 ::close( sStderr[1] );
815 }
816 ::close( fd[0] );
817 ::close( fd[1] );
818 delete[] arglistQ;
819 delete[] arglist;
820 return FALSE;
821}
822
823
824/*!
825 Asks the process to terminate. Processes can ignore this wish. If you want to
826 be sure that the process really terminates, you must use kill() instead.
827
828 The slot returns immediately: it does not wait until the process has
829 finished. When the process really exited, the signal processExited() is
830 emitted.
831
832 \sa kill() processExited()
833*/
834void QProcess::tryTerminate() const
835{
836 if ( d->proc != 0 )
837 ::kill( d->proc->pid, SIGTERM );
838}
839
840/*!
841 Terminates the process. This is not a safe way to end a process since the
842 process will not be able to do cleanup. tryTerminate() is a safer way to do
843 it, but processes might ignore a tryTerminate().
844
845 The nice way to end a process and to be sure that it is finished, is doing
846 something like this:
847 \code
848 process->tryTerminate();
849 QTimer::singleShot( 5000, process, SLOT( kill() ) );
850 \endcode
851
852 This tries to terminate the process the nice way. If the process is still
853 running after 5 seconds, it terminates the process the hard way. The timeout
854 should be chosen depending on the time the process needs to do all the
855 cleanup: use a higher value if the process is likely to do heavy computation
856 on cleanup.
857
858 The slot returns immediately: it does not wait until the process has
859 finished. When the process really exited, the signal processExited() is
860 emitted.
861
862 \sa tryTerminate() processExited()
863*/
864void QProcess::kill() const
865{
866 if ( d->proc != 0 )
867 ::kill( d->proc->pid, SIGKILL );
868}
869
870/*!
871 Returns TRUE if the process is running, otherwise FALSE.
872
873 \sa normalExit() exitStatus() processExited()
874*/
875bool QProcess::isRunning() const
876{
877 if ( d->exitValuesCalculated ) {
878#if defined(QT_QPROCESS_DEBUG)
879 qDebug( "QProcess::isRunning(): FALSE (already computed)" );
880#endif
881 return FALSE;
882 }
883 if ( d->proc == 0 )
884 return FALSE;
885 int status;
886 if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid )
887 {
888 // compute the exit values
889 QProcess *that = (QProcess*)this; // mutable
890 that->exitNormal = WIFEXITED( status ) != 0;
891 if ( exitNormal ) {
892 that->exitStat = (char)WEXITSTATUS( status );
893 }
894 d->exitValuesCalculated = TRUE;
895#if defined(QT_QPROCESS_DEBUG)
896 qDebug( "QProcess::isRunning() (PID: %d): FALSE", d->proc->pid );
897#endif
898 return FALSE;
899 }
900#if defined(QT_QPROCESS_DEBUG)
901 qDebug( "QProcess::isRunning() (PID: %d): TRUE", d->proc->pid );
902#endif
903 return TRUE;
904}
905
906/*!
907 Writes the data \a buf to the standard input of the process. The process may
908 or may not read this data.
909
910 This function returns immediately; the QProcess class might write the data at
911 a later point (you have to enter the event loop for that). When all the data
912 is written to the process, the signal wroteToStdin() is emitted. This does
913 not mean that the process really read the data, since this class only detects
914 when it was able to write the data to the operating system.
915
916 \sa wroteToStdin() closeStdin() readStdout() readStderr()
917*/
918void QProcess::writeToStdin( const QByteArray& buf )
919{
920#if defined(QT_QPROCESS_DEBUG)
921// qDebug( "QProcess::writeToStdin(): write to stdin (%d)", d->socketStdin );
922#endif
923 d->stdinBuf.enqueue( new QByteArray(buf) );
924 if ( d->notifierStdin != 0 )
925 d->notifierStdin->setEnabled( TRUE );
926}
927
928
929/*!
930 Closes standard input of the process.
931
932 This function also deletes pending data that is not written to standard input
933 yet.
934
935 \sa wroteToStdin()
936*/
937void QProcess::closeStdin()
938{
939 if ( d->proc == 0 )
940 return;
941 if ( d->proc->socketStdin !=0 ) {
942 while ( !d->stdinBuf.isEmpty() ) {
943 delete d->stdinBuf.dequeue();
944 }
945 delete d->notifierStdin;
946 d->notifierStdin = 0;
947 if ( ::close( d->proc->socketStdin ) != 0 ) {
948 qWarning( "Could not close stdin of child process" );
949 }
950#if defined(QT_QPROCESS_DEBUG)
951 qDebug( "QProcess::closeStdin(): stdin (%d) closed", d->proc->socketStdin );
952#endif
953 d->proc->socketStdin = 0;
954 }
955}
956
957
958/*
959 This private slot is called when the process has outputted data to either
960 standard output or standard error.
961*/
962void QProcess::socketRead( int fd )
963{
964 if ( d->socketReadCalled ) {
965 // the slots that are connected to the readyRead...() signals might
966 // trigger a recursive call of socketRead(). Avoid this since you get a
967 // blocking read otherwise.
968 return;
969 }
970#if defined(QT_QPROCESS_DEBUG)
971 qDebug( "QProcess::socketRead(): %d", fd );
972#endif
973 if ( fd == 0 )
974 return;
975 const int bufsize = 4096;
976 QByteArray *buffer = 0;
977 uint oldSize;
978 int n;
979 if ( fd == d->proc->socketStdout ) {
980 buffer = &d->bufStdout;
981 } else if ( fd == d->proc->socketStderr ) {
982 buffer = &d->bufStderr;
983 } else {
984 // this case should never happen, but just to be safe
985 return;
986 }
987
988 // read data
989 oldSize = buffer->size();
990 buffer->resize( oldSize + bufsize );
991 n = ::read( fd, buffer->data()+oldSize, bufsize );
992 if ( n > 0 )
993 buffer->resize( oldSize + n );
994 else
995 buffer->resize( oldSize );
996 // eof or error?
997 if ( n == 0 || n == -1 ) {
998 if ( fd == d->proc->socketStdout ) {
999#if defined(QT_QPROCESS_DEBUG)
1000 qDebug( "QProcess::socketRead(): stdout (%d) closed", fd );
1001#endif
1002 d->notifierStdout->setEnabled( FALSE );
1003 delete d->notifierStdout;
1004 d->notifierStdout = 0;
1005 ::close( d->proc->socketStdout );
1006 d->proc->socketStdout = 0;
1007 return;
1008 } else if ( fd == d->proc->socketStderr ) {
1009#if defined(QT_QPROCESS_DEBUG)
1010 qDebug( "QProcess::socketRead(): stderr (%d) closed", fd );
1011#endif
1012 d->notifierStderr->setEnabled( FALSE );
1013 delete d->notifierStderr;
1014 d->notifierStderr = 0;
1015 ::close( d->proc->socketStderr );
1016 d->proc->socketStderr = 0;
1017 return;
1018 }
1019 }
1020 // read all data that is available
1021 while ( n == bufsize ) {
1022 oldSize = buffer->size();
1023 buffer->resize( oldSize + bufsize );
1024 n = ::read( fd, buffer->data()+oldSize, bufsize );
1025 if ( n > 0 )
1026 buffer->resize( oldSize + n );
1027 else
1028 buffer->resize( oldSize );
1029 }
1030
1031 d->socketReadCalled = TRUE;
1032 if ( fd == d->proc->socketStdout ) {
1033#if defined(QT_QPROCESS_DEBUG)
1034 qDebug( "QProcess::socketRead(): %d bytes read from stdout (%d)",
1035 buffer->size()-oldSize, fd );
1036#endif
1037 emit readyReadStdout();
1038 } else if ( fd == d->proc->socketStderr ) {
1039#if defined(QT_QPROCESS_DEBUG)
1040 qDebug( "QProcess::socketRead(): %d bytes read from stderr (%d)",
1041 buffer->size()-oldSize, fd );
1042#endif
1043 emit readyReadStderr();
1044 }
1045 d->socketReadCalled = FALSE;
1046}
1047
1048
1049/*
1050 This private slot is called when the process tries to read data from standard
1051 input.
1052*/
1053void QProcess::socketWrite( int fd )
1054{
1055 if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 )
1056 return;
1057 if ( d->stdinBuf.isEmpty() ) {
1058 d->notifierStdin->setEnabled( FALSE );
1059 return;
1060 }
1061#if defined(QT_QPROCESS_DEBUG)
1062 qDebug( "QProcess::socketWrite(): write to stdin (%d)", fd );
1063#endif
1064 ssize_t ret = ::write( fd,
1065 d->stdinBuf.head()->data() + d->stdinBufRead,
1066 d->stdinBuf.head()->size() - d->stdinBufRead );
1067 if ( ret > 0 )
1068 d->stdinBufRead += ret;
1069 if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) {
1070 d->stdinBufRead = 0;
1071 delete d->stdinBuf.dequeue();
1072 if ( wroteToStdinConnected && d->stdinBuf.isEmpty() )
1073 emit wroteToStdin();
1074 socketWrite( fd );
1075 }
1076}
1077
1078/*!
1079 \internal
1080 Flushes standard input. This is useful if you want to use QProcess in a
1081 synchronous manner.
1082
1083 This function should probably go into the public API.
1084*/
1085void QProcess::flushStdin()
1086{
1087 socketWrite( d->proc->socketStdin );
1088}
1089
1090/*
1091 This private slot is only used under Windows (but moc does not know about #if
1092 defined()).
1093*/
1094void QProcess::timeout()
1095{
1096}
1097
1098
1099/*
1100 This private function is used by connectNotify() and disconnectNotify() to
1101 change the value of ioRedirection (and related behaviour)
1102*/
1103void QProcess::setIoRedirection( bool value )
1104{
1105 ioRedirection = value;
1106 if ( ioRedirection ) {
1107 if ( d->notifierStdout )
1108 d->notifierStdout->setEnabled( TRUE );
1109 if ( d->notifierStderr )
1110 d->notifierStderr->setEnabled( TRUE );
1111 } else {
1112 if ( d->notifierStdout )
1113 d->notifierStdout->setEnabled( FALSE );
1114 if ( d->notifierStderr )
1115 d->notifierStderr->setEnabled( FALSE );
1116 }
1117}
1118
1119/*
1120 This private function is used by connectNotify() and
1121 disconnectNotify() to change the value of notifyOnExit (and related
1122 behaviour)
1123*/
1124void QProcess::setNotifyOnExit( bool value )
1125{
1126 notifyOnExit = value;
1127}
1128
1129/*
1130 This private function is used by connectNotify() and disconnectNotify() to
1131 change the value of wroteToStdinConnected (and related behaviour)
1132*/
1133void QProcess::setWroteStdinConnected( bool value )
1134{
1135 wroteToStdinConnected = value;
1136}
1137
1138/*! \enum QProcess::PID
1139 \internal
1140*/
1141/*!
1142 Returns platform dependent information about the process. This can be used
1143 together with platform specific system calls.
1144
1145 Under Unix the return value is the PID of the process, or -1 if no process is
1146 belonging to this object.
1147
1148 Under Windows it is a pointer to the \c PROCESS_INFORMATION struct, or 0 if
1149 no process is belonging to this object.
1150*/
1151QProcess::PID QProcess::processIdentifier()
1152{
1153 if ( d->proc == 0 )
1154 return -1;
1155 return d->proc->pid;
1156}
1157
1158#endif // QT_NO_PROCESS
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp
index cbda247..0337a94 100644
--- a/core/launcher/transferserver.cpp
+++ b/core/launcher/transferserver.cpp
@@ -27,13 +27,14 @@
27 27
28/* we need the _OS_LINUX stuff first ! */ 28/* we need the _OS_LINUX stuff first ! */
29#include <qglobal.h> 29#include <qglobal.h>
30 30
31#ifndef _OS_LINUX_ 31#ifndef _OS_LINUX_
32 32
33extern "C" { 33extern "C"
34{
34#include <uuid/uuid.h> 35#include <uuid/uuid.h>
35#define UUID_H_INCLUDED 36#define UUID_H_INCLUDED
36} 37}
37 38
38#endif // not defined linux 39#endif // not defined linux
39 40
@@ -56,13 +57,13 @@ extern "C" {
56#include <qpe/contact.h> 57#include <qpe/contact.h>
57#include <qpe/quuid.h> 58#include <qpe/quuid.h>
58#include <qpe/version.h> 59#include <qpe/version.h>
59#include <qpe/qcopenvelope_qws.h> 60#include <qpe/qcopenvelope_qws.h>
60 61
61#include "transferserver.h" 62#include "transferserver.h"
62#include "qprocess.h" 63#include <opie/oprocess.h>
63 64
64const int block_size = 51200; 65const int block_size = 51200;
65 66
66TransferServer::TransferServer( Q_UINT16 port, QObject *parent , 67TransferServer::TransferServer( Q_UINT16 port, QObject *parent ,
67 const char* name ) 68 const char* name )
68 : QServerSocket( port, 1, parent, name ) 69 : QServerSocket( port, 1, parent, name )
@@ -70,40 +71,44 @@ TransferServer::TransferServer( Q_UINT16 port, QObject *parent ,
70 if ( !ok() ) 71 if ( !ok() )
71 qWarning( "Failed to bind to port %d", port ); 72 qWarning( "Failed to bind to port %d", port );
72} 73}
73 74
74TransferServer::~TransferServer() 75TransferServer::~TransferServer()
75{ 76{
76
77} 77}
78 78
79void TransferServer::newConnection( int socket ) 79void TransferServer::newConnection( int socket )
80{ 80{
81 (void) new ServerPI( socket, this ); 81 (void) new ServerPI( socket, this );
82} 82}
83 83
84/* 84/*
85 * small class in anonymous namespace 85 * small class in anonymous namespace
86 * to generate a QUUid for us 86 * to generate a QUUid for us
87 */ 87 */
88namespace { 88namespace
89 struct UidGen { 89{
90struct UidGen
91{
90 QString uuid(); 92 QString uuid();
91 }; 93 };
92#if !defined(_OS_LINUX_) 94#if !defined(_OS_LINUX_)
93 QString UidGen::uuid() { 95
96QString UidGen::uuid()
97{
94 uuid_t uuid; 98 uuid_t uuid;
95 uuid_generate( uuid ); 99 uuid_generate( uuid );
96 return QUUid( uuid ).toString(); 100 return QUUid( uuid ).toString();
97 } 101 }
98#else 102#else
99 /* 103 /*
100 * linux got a /proc/sys/kernel/random/uuid file 104 * linux got a /proc/sys/kernel/random/uuid file
101 * it'll generate the uuids for us 105 * it'll generate the uuids for us
102 */ 106 */
103 QString UidGen::uuid() { 107QString UidGen::uuid()
108{
104 QFile file( "/proc/sys/kernel/random/uuid" ); 109 QFile file( "/proc/sys/kernel/random/uuid" );
105 if (!file.open(IO_ReadOnly ) ) 110 if (!file.open(IO_ReadOnly ) )
106 return QString::null; 111 return QString::null;
107 112
108 QTextStream stream(&file); 113 QTextStream stream(&file);
109 114
@@ -160,13 +165,14 @@ int SyncAuthentication::isAuthorized(QHostAddress peeraddress)
160 ? 0xffffffff : (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits)); 165 ? 0xffffffff : (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits));
161 return (peeraddress.ip4Addr() & mask) == auth_peer; 166 return (peeraddress.ip4Addr() & mask) == auth_peer;
162} 167}
163 168
164bool SyncAuthentication::checkUser( const QString& user ) 169bool SyncAuthentication::checkUser( const QString& user )
165{ 170{
166 if ( user.isEmpty() ) return FALSE; 171 if ( user.isEmpty() )
172 return FALSE;
167 QString euser = loginName(); 173 QString euser = loginName();
168 return user == euser; 174 return user == euser;
169} 175}
170 176
171bool SyncAuthentication::checkPassword( const QString& password ) 177bool SyncAuthentication::checkPassword( const QString& password )
172{ 178{
@@ -227,18 +233,18 @@ bool SyncAuthentication::checkPassword( const QString& password )
227 // Unrecognized system. Be careful... 233 // Unrecognized system. Be careful...
228 234
229 if ( (denials > 2 && now < lastdenial+600) 235 if ( (denials > 2 && now < lastdenial+600)
230 || QMessageBox::warning(0,tr("Sync Connection"), 236 || QMessageBox::warning(0,tr("Sync Connection"),
231 tr("<p>An unrecognized system is requesting access to this device." 237 tr("<p>An unrecognized system is requesting access to this device."
232 "<p>If you have just initiated a Sync for the first time, this is normal."), 238 "<p>If you have just initiated a Sync for the first time, this is normal."),
233 tr("Allow"),tr("Deny"), 0, 1, 1 ) ==1 ) 239 tr("Allow"), tr("Deny"), 0, 1, 1 ) == 1 ) {
234 {
235 denials++; 240 denials++;
236 lastdenial=now; 241 lastdenial=now;
237 return FALSE; 242 return FALSE;
238 } else { 243 }
244 else {
239 denials=0; 245 denials=0;
240 cfg.writeEntry("Passwords",pwds+" "+cpassword); 246 cfg.writeEntry("Passwords",pwds+" "+cpassword);
241 return TRUE; 247 return TRUE;
242 } 248 }
243 } 249 }
244 250
@@ -253,16 +259,18 @@ ServerPI::ServerPI( int socket, QObject *parent , const char* name )
253 setSocket( socket ); 259 setSocket( socket );
254 260
255 peerport = peerPort(); 261 peerport = peerPort();
256 peeraddress = peerAddress(); 262 peeraddress = peerAddress();
257 263
258#ifndef INSECURE 264#ifndef INSECURE
265
259 if ( !SyncAuthentication::isAuthorized(peeraddress) ) { 266 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
260 state = Forbidden; 267 state = Forbidden;
261 startTimer( 0 ); 268 startTimer( 0 );
262 } else 269 }
270 else
263#endif 271#endif
264 { 272 {
265 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 273 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
266 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 274 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
267 275
268 passiv = FALSE; 276 passiv = FALSE;
@@ -290,13 +298,12 @@ ServerPI::ServerPI( int socket, QObject *parent , const char* name )
290 SLOT( newConnection( int ) ) ); 298 SLOT( newConnection( int ) ) );
291 } 299 }
292} 300}
293 301
294ServerPI::~ServerPI() 302ServerPI::~ServerPI()
295{ 303{
296
297} 304}
298 305
299void ServerPI::connectionClosed() 306void ServerPI::connectionClosed()
300{ 307{
301 // qDebug( "Debug: Connection closed" ); 308 // qDebug( "Debug: Connection closed" );
302 delete this; 309 delete this;
@@ -348,13 +355,14 @@ bool ServerPI::checkWriteFile( const QString& file )
348void ServerPI::process( const QString& message ) 355void ServerPI::process( const QString& message )
349{ 356{
350 //qDebug( "Command: %s", message.latin1() ); 357 //qDebug( "Command: %s", message.latin1() );
351 358
352 // split message using "," as separator 359 // split message using "," as separator
353 QStringList msg = QStringList::split( " ", message ); 360 QStringList msg = QStringList::split( " ", message );
354 if ( msg.isEmpty() ) return; 361 if ( msg.isEmpty() )
362 return ;
355 363
356 // command token 364 // command token
357 QString cmd = msg[0].upper(); 365 QString cmd = msg[0].upper();
358 366
359 // argument token 367 // argument token
360 QString arg; 368 QString arg;
@@ -587,13 +595,14 @@ void ServerPI::process( const QString& message )
587 else { 595 else {
588 QFile file( absFilePath( args ) ) ; 596 QFile file( absFilePath( args ) ) ;
589 if ( file.remove() ) { 597 if ( file.remove() ) {
590 send( "250 Requested file action okay, completed" ); 598 send( "250 Requested file action okay, completed" );
591 QCopEnvelope e("QPE/System", "linkChanged(QString)" ); 599 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
592 e << file.name(); 600 e << file.name();
593 } else { 601 }
602 else {
594 send( "550 Requested action not taken" ); 603 send( "550 Requested action not taken" );
595 } 604 }
596 } 605 }
597 } 606 }
598 607
599 // remove directory (RMD) 608 // remove directory (RMD)
@@ -731,13 +740,14 @@ void ServerPI::sendFile( const QString& file )
731 newConnection( waitsocket ); 740 newConnection( waitsocket );
732 } 741 }
733 else { 742 else {
734 QStringList targets; 743 QStringList targets;
735 if ( backupRestoreGzip( file, targets ) ) 744 if ( backupRestoreGzip( file, targets ) )
736 dtp->sendGzipFile( file, targets, peeraddress, peerport ); 745 dtp->sendGzipFile( file, targets, peeraddress, peerport );
737 else dtp->sendFile( file, peeraddress, peerport ); 746 else
747 dtp->sendFile( file, peeraddress, peerport );
738 } 748 }
739} 749}
740 750
741void ServerPI::retrieveFile( const QString& file ) 751void ServerPI::retrieveFile( const QString& file )
742{ 752{
743 if ( passiv ) { 753 if ( passiv ) {
@@ -755,13 +765,14 @@ void ServerPI::retrieveFile( const QString& file )
755 } 765 }
756} 766}
757 767
758bool ServerPI::parsePort( const QString& pp ) 768bool ServerPI::parsePort( const QString& pp )
759{ 769{
760 QStringList p = QStringList::split( ",", pp ); 770 QStringList p = QStringList::split( ",", pp );
761 if ( p.count() != 6 ) return FALSE; 771 if ( p.count() != 6 )
772 return FALSE;
762 773
763 // h1,h2,h3,h4,p1,p2 774 // h1,h2,h3,h4,p1,p2
764 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + 775 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) +
765 ( p[2].toInt() << 8 ) + p[3].toInt() ); 776 ( p[2].toInt() << 8 ) + p[3].toInt() );
766 peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); 777 peerport = ( p[4].toInt() << 8 ) + p[5].toInt();
767 return TRUE; 778 return TRUE;
@@ -807,13 +818,14 @@ bool ServerPI::sendList( const QString& arg )
807 QString fn = arg; 818 QString fn = arg;
808 819
809 if ( fn.isEmpty() ) 820 if ( fn.isEmpty() )
810 fn = directory.path(); 821 fn = directory.path();
811 822
812 QFileInfo fi( fn ); 823 QFileInfo fi( fn );
813 if ( !fi.exists() ) return FALSE; 824 if ( !fi.exists() )
825 return FALSE;
814 826
815 // return file listing 827 // return file listing
816 if ( fi.isFile() ) { 828 if ( fi.isFile() ) {
817 ts << fileListing( &fi ) << endl; 829 ts << fileListing( &fi ) << endl;
818 } 830 }
819 831
@@ -855,13 +867,14 @@ bool ServerPI::sendList( const QString& arg )
855 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); 867 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport );
856 return TRUE; 868 return TRUE;
857} 869}
858 870
859QString ServerPI::fileListing( QFileInfo *info ) 871QString ServerPI::fileListing( QFileInfo *info )
860{ 872{
861 if ( !info ) return QString::null; 873 if ( !info )
874 return QString::null;
862 QString s; 875 QString s;
863 876
864 // type char 877 // type char
865 if ( info->isDir() ) 878 if ( info->isDir() )
866 s += "d"; 879 s += "d";
867 else if ( info->isSymLink() ) 880 else if ( info->isSymLink() )
@@ -905,47 +918,67 @@ QString ServerPI::fileListing( QFileInfo *info )
905 918
906 return s; 919 return s;
907} 920}
908 921
909QString ServerPI::permissionString( QFileInfo *info ) 922QString ServerPI::permissionString( QFileInfo *info )
910{ 923{
911 if ( !info ) return QString( "---------" ); 924 if ( !info )
925 return QString( "---------" );
912 QString s; 926 QString s;
913 927
914 // user 928 // user
915 if ( info->permission( QFileInfo::ReadUser ) ) s += "r"; 929 if ( info->permission( QFileInfo::ReadUser ) )
916 else s += "-"; 930 s += "r";
917 if ( info->permission( QFileInfo::WriteUser ) ) s += "w"; 931 else
918 else s += "-"; 932 s += "-";
919 if ( info->permission( QFileInfo::ExeUser ) ) s += "x"; 933 if ( info->permission( QFileInfo::WriteUser ) )
920 else s += "-"; 934 s += "w";
935 else
936 s += "-";
937 if ( info->permission( QFileInfo::ExeUser ) )
938 s += "x";
939 else
940 s += "-";
921 941
922 // group 942 // group
923 if ( info->permission( QFileInfo::ReadGroup ) ) s += "r"; 943 if ( info->permission( QFileInfo::ReadGroup ) )
924 else s += "-"; 944 s += "r";
925 if ( info->permission( QFileInfo::WriteGroup ) )s += "w"; 945 else
926 else s += "-"; 946 s += "-";
927 if ( info->permission( QFileInfo::ExeGroup ) ) s += "x"; 947 if ( info->permission( QFileInfo::WriteGroup ) )
928 else s += "-"; 948 s += "w";
949 else
950 s += "-";
951 if ( info->permission( QFileInfo::ExeGroup ) )
952 s += "x";
953 else
954 s += "-";
929 955
930 // exec 956 // exec
931 if ( info->permission( QFileInfo::ReadOther ) ) s += "r"; 957 if ( info->permission( QFileInfo::ReadOther ) )
932 else s += "-"; 958 s += "r";
933 if ( info->permission( QFileInfo::WriteOther ) ) s += "w"; 959 else
934 else s += "-"; 960 s += "-";
935 if ( info->permission( QFileInfo::ExeOther ) ) s += "x"; 961 if ( info->permission( QFileInfo::WriteOther ) )
936 else s += "-"; 962 s += "w";
963 else
964 s += "-";
965 if ( info->permission( QFileInfo::ExeOther ) )
966 s += "x";
967 else
968 s += "-";
937 969
938 return s; 970 return s;
939} 971}
940 972
941void ServerPI::newConnection( int socket ) 973void ServerPI::newConnection( int socket )
942{ 974{
943 //qDebug( "New incomming connection" ); 975 //qDebug( "New incomming connection" );
944 976
945 if ( !passiv ) return; 977 if ( !passiv )
978 return ;
946 979
947 if ( wait[SendFile] ) { 980 if ( wait[SendFile] ) {
948 QStringList targets; 981 QStringList targets;
949 if ( backupRestoreGzip( waitfile, targets ) ) 982 if ( backupRestoreGzip( waitfile, targets ) )
950 dtp->sendGzipFile( waitfile, targets ); 983 dtp->sendGzipFile( waitfile, targets );
951 else 984 else
@@ -975,13 +1008,14 @@ void ServerPI::newConnection( int socket )
975 for( int i = 0; i < 4; i++ ) 1008 for( int i = 0; i < 4; i++ )
976 wait[i] = FALSE; 1009 wait[i] = FALSE;
977} 1010}
978 1011
979QString ServerPI::absFilePath( const QString& file ) 1012QString ServerPI::absFilePath( const QString& file )
980{ 1013{
981 if ( file.isEmpty() ) return file; 1014 if ( file.isEmpty() )
1015 return file;
982 1016
983 QString filepath( file ); 1017 QString filepath( file );
984 if ( file[0] != "/" ) 1018 if ( file[0] != "/" )
985 filepath = directory.path() + "/" + file; 1019 filepath = directory.path() + "/" + file;
986 1020
987 return filepath; 1021 return filepath;
@@ -1001,28 +1035,25 @@ retrieveTargzProc( 0 ), gzipProc( 0 )
1001 1035
1002 connect( this, SIGNAL( connected() ), SLOT( connected() ) ); 1036 connect( this, SIGNAL( connected() ), SLOT( connected() ) );
1003 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 1037 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
1004 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) ); 1038 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) );
1005 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); 1039 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) );
1006 1040
1007 gzipProc = new QProcess( this, "gzipProc" ); 1041 gzipProc = new OProcess( this, "gzipProc" );
1008 gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout );
1009 1042
1010 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); 1043 createTargzProc = new OProcess( QString("tar"), this, "createTargzProc");
1011 createTargzProc->setCommunication( QProcess::Stdout );
1012 createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 1044 createTargzProc->setWorkingDirectory( QDir::rootDirPath() );
1013 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); 1045 connect( createTargzProc, SIGNAL( processExited(OProcess *) ), SLOT( targzDone() ) );
1014 1046
1015 QStringList args = "tar"; 1047 QStringList args = "tar";
1016 args += "-xv"; 1048 args += "-xv";
1017 retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" ); 1049 retrieveTargzProc = new OProcess( args, this, "retrieveTargzProc" );
1018 retrieveTargzProc->setCommunication( QProcess::Stdin );
1019 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 1050 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() );
1020 connect( retrieveTargzProc, SIGNAL( processExited() ), 1051 connect( retrieveTargzProc, SIGNAL( processExited(OProcess *) ),
1021 SIGNAL( completed() ) ); 1052 SIGNAL( completed() ) );
1022 connect( retrieveTargzProc, SIGNAL( processExited() ), 1053 connect( retrieveTargzProc, SIGNAL( processExited(OProcess *) ),
1023 SLOT( extractTarDone() ) ); 1054 SLOT( extractTarDone() ) );
1024} 1055}
1025 1056
1026ServerDTP::~ServerDTP() 1057ServerDTP::~ServerDTP()
1027{ 1058{
1028 buf.close(); 1059 buf.close();
@@ -1031,12 +1062,13 @@ ServerDTP::~ServerDTP()
1031} 1062}
1032 1063
1033void ServerDTP::extractTarDone() 1064void ServerDTP::extractTarDone()
1034{ 1065{
1035 qDebug("extract done"); 1066 qDebug("extract done");
1036#ifndef QT_NO_COP 1067#ifndef QT_NO_COP
1068
1037 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" ); 1069 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" );
1038 e << file.name(); 1070 e << file.name();
1039#endif 1071#endif
1040} 1072}
1041 1073
1042void ServerDTP::connected() 1074void ServerDTP::connected()
@@ -1055,13 +1087,14 @@ void ServerDTP::connected()
1055 bytes_written = 0; 1087 bytes_written = 0;
1056 if ( file.size() == 0 ) { 1088 if ( file.size() == 0 ) {
1057 //make sure it doesn't hang on empty files 1089 //make sure it doesn't hang on empty files
1058 file.close(); 1090 file.close();
1059 emit completed(); 1091 emit completed();
1060 mode = Idle; 1092 mode = Idle;
1061 } else { 1093 }
1094 else {
1062 1095
1063 if( !file.atEnd() ) { 1096 if( !file.atEnd() ) {
1064 QCString s; 1097 QCString s;
1065 s.resize( block_size ); 1098 s.resize( block_size );
1066 int bytes = file.readBlock( s.data(), block_size ); 1099 int bytes = file.readBlock( s.data(), block_size );
1067 writeBlock( s.data(), bytes ); 1100 writeBlock( s.data(), bytes );
@@ -1074,16 +1107,16 @@ void ServerDTP::connected()
1074 qWarning("Previous tar --gzip process is still running; killing it..."); 1107 qWarning("Previous tar --gzip process is still running; killing it...");
1075 createTargzProc->kill(); 1108 createTargzProc->kill();
1076 } 1109 }
1077 1110
1078 bytes_written = 0; 1111 bytes_written = 0;
1079 qDebug("==>start send tar process"); 1112 qDebug("==>start send tar process");
1080 if ( !createTargzProc->start() ) 1113 if ( !createTargzProc->start(OProcess::NotifyOnExit, OProcess::Stdout) )
1081 qWarning("Error starting %s or %s", 1114 qWarning("Error starting %s or %s",
1082 createTargzProc->arguments().join(" ").latin1(), 1115 createTargzProc->args()[0].data(),
1083 gzipProc->arguments().join(" ").latin1() ); 1116 gzipProc->args()[0].data());
1084 break; 1117 break;
1085 case SendBuffer: 1118 case SendBuffer:
1086 if ( !buf.open( IO_ReadOnly) ) { 1119 if ( !buf.open( IO_ReadOnly) ) {
1087 emit failed(); 1120 emit failed();
1088 mode = Idle; 1121 mode = Idle;
1089 return; 1122 return;
@@ -1209,59 +1242,58 @@ void ServerDTP::readyRead()
1209 s.resize( bytesAvailable() ); 1242 s.resize( bytesAvailable() );
1210 readBlock( s.data(), bytesAvailable() ); 1243 readBlock( s.data(), bytesAvailable() );
1211 file.writeBlock( s.data(), s.size() ); 1244 file.writeBlock( s.data(), s.size() );
1212 } 1245 }
1213 else if ( RetrieveGzipFile == mode ) { 1246 else if ( RetrieveGzipFile == mode ) {
1214 if ( !gzipProc->isRunning() ) 1247 if ( !gzipProc->isRunning() )
1215 gzipProc->start(); 1248 gzipProc->start(OProcess::NotifyOnExit, (OProcess::Communication) ( OProcess::Stdin | OProcess::Stdout ));
1216 1249
1217 QByteArray s; 1250 QByteArray s;
1218 s.resize( bytesAvailable() ); 1251 s.resize( bytesAvailable() );
1219 readBlock( s.data(), bytesAvailable() ); 1252 readBlock( s.data(), bytesAvailable() );
1220 gzipProc->writeToStdin( s ); 1253 gzipProc->writeStdin( s.data(), s.size() );
1221 qDebug("wrote %d bytes to ungzip ", s.size() ); 1254 qDebug("wrote %d bytes to ungzip ", s.size() );
1222 } 1255 }
1223 // retrieve buffer mode 1256 // retrieve buffer mode
1224 else if ( RetrieveBuffer == mode ) { 1257 else if ( RetrieveBuffer == mode ) {
1225 QCString s; 1258 QCString s;
1226 s.resize( bytesAvailable() ); 1259 s.resize( bytesAvailable() );
1227 readBlock( s.data(), bytesAvailable() ); 1260 readBlock( s.data(), bytesAvailable() );
1228 buf.writeBlock( s.data(), s.size() ); 1261 buf.writeBlock( s.data(), s.size() );
1229 } 1262 }
1230} 1263}
1231 1264
1232void ServerDTP::writeTargzBlock() 1265void ServerDTP::writeTargzBlock(OProcess *, char *buffer, int buflen)
1233{ 1266{
1234 QByteArray block = gzipProc->readStdout(); 1267 writeBlock( buffer, buflen );
1235 writeBlock( block.data(), block.size() ); 1268 qDebug("writeTargzBlock %d", buflen);
1236 qDebug("writeTargzBlock %d", block.size());
1237 if ( !createTargzProc->isRunning() ) { 1269 if ( !createTargzProc->isRunning() ) {
1238 qDebug("tar and gzip done"); 1270 qDebug("tar and gzip done");
1239 emit completed(); 1271 emit completed();
1240 mode = Idle; 1272 mode = Idle;
1241 disconnect( gzipProc, SIGNAL( readyReadStdout() ), 1273 disconnect( gzipProc, SIGNAL( receivedStdout(OProcess *, char *, int ) ),
1242 this, SLOT( writeTargzBlock() ) ); 1274 this, SLOT( writeTargzBlock(OProcess *, char *, int) ) );
1243 } 1275 }
1244} 1276}
1245 1277
1246void ServerDTP::targzDone() 1278void ServerDTP::targzDone()
1247{ 1279{
1248 //qDebug("targz done"); 1280 //qDebug("targz done");
1249 disconnect( createTargzProc, SIGNAL( readyReadStdout() ), 1281 disconnect( createTargzProc, SIGNAL( receivedStdout(OProcess *, char *, int) ),
1250 this, SLOT( gzipTarBlock() ) ); 1282 this, SLOT( gzipTarBlock(OProcess *, char *, int) ) );
1251 gzipProc->closeStdin(); 1283 gzipProc->closeStdin();
1252} 1284}
1253 1285
1254void ServerDTP::gzipTarBlock() 1286void ServerDTP::gzipTarBlock(OProcess *, char *buffer, int buflen)
1255{ 1287{
1256 //qDebug("gzipTarBlock"); 1288 //qDebug("gzipTarBlock");
1257 if ( !gzipProc->isRunning() ) { 1289 if ( !gzipProc->isRunning() ) {
1258 //qDebug("auto start gzip proc"); 1290 //qDebug("auto start gzip proc");
1259 gzipProc->start(); 1291 gzipProc->start(OProcess::NotifyOnExit, (OProcess::Communication) ( OProcess::Stdin | OProcess::Stdout ));
1260 } 1292 }
1261 gzipProc->writeToStdin( createTargzProc->readStdout() ); 1293 gzipProc->writeStdin( buffer, buflen );
1262} 1294}
1263 1295
1264void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) 1296void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
1265{ 1297{
1266 file.setName( fn ); 1298 file.setName( fn );
1267 mode = SendFile; 1299 mode = SendFile;
@@ -1289,40 +1321,42 @@ void ServerDTP::sendGzipFile( const QString &fn,
1289 file.setName( fn ); 1321 file.setName( fn );
1290 1322
1291 QStringList args = "tar"; 1323 QStringList args = "tar";
1292 args += "-cv"; 1324 args += "-cv";
1293 args += archiveTargets; 1325 args += archiveTargets;
1294 qDebug("sendGzipFile %s", args.join(" ").latin1() ); 1326 qDebug("sendGzipFile %s", args.join(" ").latin1() );
1295 createTargzProc->setArguments( args ); 1327 createTargzProc->clearArguments( );
1328 *createTargzProc << args;
1296 connect( createTargzProc, 1329 connect( createTargzProc,
1297 SIGNAL( readyReadStdout() ), SLOT( gzipTarBlock() ) ); 1330 SIGNAL( receivedStdout(OProcess *, char *, int) ), SLOT( gzipTarBlock(OProcess *, char *, int) ) );
1298 1331
1299 gzipProc->setArguments( "gzip" ); 1332 gzipProc->clearArguments( );
1300 connect( gzipProc, SIGNAL( readyReadStdout() ), 1333 *gzipProc << "gzip";
1301 SLOT( writeTargzBlock() ) ); 1334 connect( gzipProc, SIGNAL( receivedStdout(OProcess *, char *, int) ),
1335 SLOT( writeTargzBlock(OProcess *, char *, int) ) );
1302} 1336}
1303 1337
1304void ServerDTP::gunzipDone() 1338void ServerDTP::gunzipDone()
1305{ 1339{
1306 qDebug("gunzipDone"); 1340 qDebug("gunzipDone");
1307 disconnect( gzipProc, SIGNAL( processExited() ), 1341 disconnect( gzipProc, SIGNAL( processExited() ),
1308 this, SLOT( gunzipDone() ) ); 1342 this, SLOT( gunzipDone() ) );
1309 retrieveTargzProc->closeStdin(); 1343 retrieveTargzProc->closeStdin();
1310 disconnect( gzipProc, SIGNAL( readyReadStdout() ), 1344 disconnect( gzipProc, SIGNAL( receivedStdout(OProcess *, char *, int) ),
1311 this, SLOT( tarExtractBlock() ) ); 1345 this, SLOT( tarExtractBlock(OProcess *, char *, int) ) );
1312} 1346}
1313 1347
1314void ServerDTP::tarExtractBlock() 1348void ServerDTP::tarExtractBlock(OProcess *, char *buffer, int buflen)
1315{ 1349{
1316 qDebug("ungzipTarBlock"); 1350 qDebug("tarExtractBlock");
1317 if ( !retrieveTargzProc->isRunning() ) { 1351 if ( !retrieveTargzProc->isRunning() ) {
1318 qDebug("auto start ungzip proc"); 1352 qDebug("auto start ungzip proc");
1319 if ( !retrieveTargzProc->start() ) 1353 if ( !retrieveTargzProc->start(OProcess::NotifyOnExit, OProcess::Stdin) )
1320 qWarning(" failed to start tar -x process"); 1354 qWarning(" failed to start tar -x process");
1321 } 1355 }
1322 retrieveTargzProc->writeToStdin( gzipProc->readStdout() ); 1356 retrieveTargzProc->writeStdin( buffer, buflen );
1323} 1357}
1324 1358
1325 1359
1326void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) 1360void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
1327{ 1361{
1328 file.setName( fn ); 1362 file.setName( fn );
@@ -1339,13 +1373,14 @@ void ServerDTP::retrieveFile( const QString fn )
1339void ServerDTP::retrieveGzipFile( const QString &fn ) 1373void ServerDTP::retrieveGzipFile( const QString &fn )
1340{ 1374{
1341 qDebug("retrieveGzipFile %s", fn.latin1()); 1375 qDebug("retrieveGzipFile %s", fn.latin1());
1342 file.setName( fn ); 1376 file.setName( fn );
1343 mode = RetrieveGzipFile; 1377 mode = RetrieveGzipFile;
1344 1378
1345 gzipProc->setArguments( "gunzip" ); 1379 gzipProc->clearArguments();
1380 *gzipProc << "gunzip";
1346 connect( gzipProc, SIGNAL( readyReadStdout() ), 1381 connect( gzipProc, SIGNAL( readyReadStdout() ),
1347 SLOT( tarExtractBlock() ) ); 1382 SLOT( tarExtractBlock() ) );
1348 connect( gzipProc, SIGNAL( processExited() ), 1383 connect( gzipProc, SIGNAL( processExited() ),
1349 SLOT( gunzipDone() ) ); 1384 SLOT( gunzipDone() ) );
1350} 1385}
1351 1386
diff --git a/core/launcher/transferserver.h b/core/launcher/transferserver.h
index a3bb060..1c5ab4b 100644
--- a/core/launcher/transferserver.h
+++ b/core/launcher/transferserver.h
@@ -21,13 +21,13 @@
21#include <qsocket.h> 21#include <qsocket.h>
22#include <qdir.h> 22#include <qdir.h>
23#include <qfile.h> 23#include <qfile.h>
24#include <qbuffer.h> 24#include <qbuffer.h>
25 25
26class QFileInfo; 26class QFileInfo;
27class QProcess; 27class OProcess;
28class TransferServer : public QServerSocket 28class TransferServer : public QServerSocket
29{ 29{
30 Q_OBJECT 30 Q_OBJECT
31 31
32public: 32public:
33 TransferServer( Q_UINT16 port, QObject *parent = 0, const char* name = 0 ); 33 TransferServer( Q_UINT16 port, QObject *parent = 0, const char* name = 0 );
@@ -89,29 +89,29 @@ signals:
89 89
90private slots: 90private slots:
91 void connectionClosed(); 91 void connectionClosed();
92 void connected(); 92 void connected();
93 void bytesWritten( int bytes ); 93 void bytesWritten( int bytes );
94 void readyRead(); 94 void readyRead();
95 void writeTargzBlock(); 95 void writeTargzBlock(OProcess *, char *, int);
96 void targzDone(); 96 void targzDone();
97 97
98 void gzipTarBlock(); 98 void gzipTarBlock(OProcess *, char *, int);
99 void tarExtractBlock(); 99 void tarExtractBlock(OProcess *, char *, int);
100 void gunzipDone(); 100 void gunzipDone();
101 void extractTarDone(); 101 void extractTarDone();
102 102
103private: 103private:
104 104
105 unsigned long bytes_written; 105 unsigned long bytes_written;
106 Mode mode; 106 Mode mode;
107 QFile file; 107 QFile file;
108 QBuffer buf; 108 QBuffer buf;
109 QProcess *createTargzProc; 109 OProcess *createTargzProc;
110 QProcess *retrieveTargzProc; 110 OProcess *retrieveTargzProc;
111 QProcess *gzipProc; 111 OProcess *gzipProc;
112}; 112};
113 113
114class ServerSocket : public QServerSocket 114class ServerSocket : public QServerSocket
115{ 115{
116 Q_OBJECT 116 Q_OBJECT
117 117