author | ar <ar> | 2004-05-02 16:35:53 (UTC) |
---|---|---|
committer | ar <ar> | 2004-05-02 16:35:53 (UTC) |
commit | f8add41b2e0b0371754521b44d95f87fa70a6ff2 (patch) (side-by-side diff) | |
tree | 5e31a4f036ff20fc3a5961e99a17fc141caf9b8b | |
parent | 34f1234b010fa80f9ca06e65f46130713f7362d9 (diff) | |
download | opie-f8add41b2e0b0371754521b44d95f87fa70a6ff2.zip opie-f8add41b2e0b0371754521b44d95f87fa70a6ff2.tar.gz opie-f8add41b2e0b0371754521b44d95f87fa70a6ff2.tar.bz2 |
- convert qDebug to odebug
-rw-r--r-- | core/launcher/documentlist.cpp | 8 | ||||
-rw-r--r-- | core/launcher/qprocess_unix.cpp | 646 | ||||
-rw-r--r-- | core/launcher/screensaver.cpp | 386 | ||||
-rw-r--r-- | core/launcher/server.cpp | 434 | ||||
-rw-r--r-- | core/launcher/transferserver.cpp | 851 |
5 files changed, 1164 insertions, 1161 deletions
diff --git a/core/launcher/documentlist.cpp b/core/launcher/documentlist.cpp index 19ceb0f..44ceb0c 100644 --- a/core/launcher/documentlist.cpp +++ b/core/launcher/documentlist.cpp @@ -134,551 +134,551 @@ void DocumentList::add( const DocLnk& doc ) d->serverGui->documentAdded( doc ); } void DocumentList::start() { resume(); } void DocumentList::pause() { //odebug << "pause " << d->tid << "" << oendl; killTimer( d->tid ); d->tid = 0; } void DocumentList::resume() { if ( d->tid == 0 ) { d->tid = startTimer( 20 ); //odebug << "resumed " << d->tid << "" << oendl; } } /* void DocumentList::resend() { // Re-emits all the added items to the list (firstly letting everyone know to // clear what they have as it is being sent again) pause(); emit allRemoved(); QTimer::singleShot( 5, this, SLOT( resendWorker() ) ); } void DocumentList::resendWorker() { const QList<DocLnk> &list = d->dls.children(); for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) add( *(*it) ); resume(); } */ void DocumentList::rescan() { //odebug << "rescan" << oendl; pause(); d->initialize(); resume(); } void DocumentList::timerEvent( QTimerEvent *te ) { if ( te->timerId() == d->tid ) { // Do 3 at a time if ( d->serverGui ) d->serverGui->aboutToAddBegin(); for (int i = 0; i < 3; i++ ) { const DocLnk *lnk = d->iterate(); if ( lnk ) { add( *lnk ); } else { // stop when done pause(); if ( d->serverGui ) d->serverGui->documentScanningProgress( 100 ); if ( d->needToSendAllDocLinks ) sendAllDocLinks(); break; } } if ( d->serverGui ) d->serverGui->aboutToAddEnd(); } } void DocumentList::reloadAppLnks() { if ( d->sendAppLnks && d->serverGui ) { d->serverGui->applicationScanningProgress( 0 ); d->serverGui->allApplicationsRemoved(); } delete appLnkSet; appLnkSet = new AppLnkSet( MimeType::appsFolderName() ); if ( d->sendAppLnks && d->serverGui ) { static QStringList prevTypeList; QStringList types = appLnkSet->types(); for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) { if ( !(*ittypes).isEmpty() ) { if ( !prevTypeList.contains(*ittypes) ) { QString name = appLnkSet->typeName(*ittypes); QPixmap pm = appLnkSet->typePixmap(*ittypes); QPixmap bgPm = appLnkSet->typeBigPixmap(*ittypes); if (pm.isNull()) { QImage img( Resource::loadImage( "UnknownDocument" ) ); pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ); } //odebug << "adding type " << (*ittypes) << "" << oendl; // ### our current launcher expects docs tab to be last d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm ); } prevTypeList.remove(*ittypes); } } for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) { //odebug << "removing type " << (*ittypes) << "" << oendl; d->serverGui->typeRemoved(*ittypes); } prevTypeList = types; } QListIterator<AppLnk> itapp( appLnkSet->children() ); AppLnk* l; while ( (l=itapp.current()) ) { ++itapp; if ( d->sendAppLnks && d->serverGui ) d->serverGui->applicationAdded( l->type(), *l ); } if ( d->sendAppLnks && d->serverGui ) d->serverGui->applicationScanningProgress( 100 ); } void DocumentList::reloadDocLnks() { if ( !d->scanDocs ) return; if ( d->sendDocLnks && d->serverGui ) { d->serverGui->documentScanningProgress( 0 ); d->serverGui->allDocumentsRemoved(); } rescan(); } void DocumentList::linkChanged( QString arg ) { //odebug << "linkchanged( " << arg << " )" << oendl; if ( arg.isNull() || OGlobal::isAppLnkFileName( arg ) ) { reloadAppLnks(); } else { const QList<DocLnk> &list = d->dls.children(); QListIterator<DocLnk> it( list ); while ( it.current() ) { DocLnk *doc = it.current(); ++it; if ( ( doc->linkFileKnown() && doc->linkFile() == arg ) || ( doc->fileKnown() && doc->file() == arg ) ) { //odebug << "found old link" << oendl; DocLnk* dl = new DocLnk( arg ); // add new one if it exists and matches the mimetype if ( d->store( dl ) ) { // Existing link has been changed, send old link ref and a ref // to the new link //odebug << "change case" << oendl; if ( d->serverGui ) d->serverGui->documentChanged( *doc, *dl ); } else { // Link has been removed or doesn't match the mimetypes any more // so we aren't interested in it, so take it away from the list //odebug << "removal case" << oendl; if ( d->serverGui ) d->serverGui->documentRemoved( *doc ); } d->dls.remove( doc ); // remove old link from docLnkSet delete doc; return; } } // Didn't find existing link, must be new DocLnk* dl = new DocLnk( arg ); if ( d->store( dl ) ) { // Add if it's a link we are interested in //odebug << "add case" << oendl; add( *dl ); } } } void DocumentList::restoreDone() { reloadAppLnks(); reloadDocLnks(); } void DocumentList::DiffAppLnks() { static AppLnkSet *appLnkSet2; appLnkSet2 = new AppLnkSet( MimeType::appsFolderName() ); if ( d->sendAppLnks && d->serverGui ) { static QStringList prevTypeList = appLnkSet->types(); QStringList types = appLnkSet2->types(); for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) { if ( !(*ittypes).isEmpty() ) { if ( !prevTypeList.contains(*ittypes) ) { QString name = appLnkSet2->typeName(*ittypes); QPixmap pm = appLnkSet2->typePixmap(*ittypes); QPixmap bgPm = appLnkSet2->typeBigPixmap(*ittypes); if (pm.isNull()) { QImage img( Resource::loadImage( "UnknownDocument" ) ); pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ); } odebug << "adding type " << (*ittypes) << "" << oendl; // ### our current launcher expects docs tab to be last d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm ); } prevTypeList.remove(*ittypes); } } for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) { odebug << "removing type " << (*ittypes) << "" << oendl; d->serverGui->typeRemoved(*ittypes); } prevTypeList = types; } QListIterator<AppLnk> it1( appLnkSet->children() ); QListIterator<AppLnk> it2( appLnkSet2->children() ); AppLnk *i; AppLnk *j; bool found; while ( (j=it2.current()) ) { it1 = appLnkSet->children(); found = false; while ( (i=it1.current()) ){ if (strcmp(i->name().ascii(),j->name().ascii()) == 0) found = true; ++it1; } if (!found) { - qDebug("Item %s needs to be added",j->name().ascii() ); + odebug << "Item " << j->name().ascii() << " needs to be added" << oendl; d->serverGui->applicationAdded( j->type(), *j ); } ++it2; } it1 = appLnkSet->children(); while ( (i=it1.current()) ) { it2 = appLnkSet2->children(); found = false; while ( (j=it2.current()) ){ if (strcmp(i->name().ascii(),j->name().ascii()) == 0) found = true; ++it2; } if (!found) { - qDebug("Item %s needs to be removed",i->name().ascii() ); + odebug << "Item " << i->name().ascii() << " needs to be removed" << oendl; d->serverGui->applicationRemoved( i->type(), *i ); } ++it1; } delete appLnkSet; appLnkSet = appLnkSet2; } void DocumentList::storageChanged() { QTime t; // ### can implement better t.start(); DiffAppLnks(); // reloadAppLnks(); - qDebug("Reload App links took %i ms",t.elapsed() ); + odebug << "Reload App links took " << t.elapsed() << " ms" << oendl; reloadDocLnks(); // odebug << "Reload links took " << t.elapsed() << " ms " << oendl; - qDebug("Reload All links took %i ms",t.elapsed() ); + odebug << "Reload All links took " << t.elapsed() << " ms" << oendl; // ### Optimization opportunity // Could be a bit more intelligent and somehow work out which // mtab entry has changed and then only scan that and add and remove // links appropriately. // rescan(); } void DocumentList::sendAllDocLinks() { if ( d->tid != 0 ) { // We are in the middle of scanning, set a flag so // we do this when we finish our scanning d->needToSendAllDocLinks = true; return; } QString contents; Categories cats; for ( QListIterator<DocLnk> it( d->dls.children() ); it.current(); ++it ) { DocLnk *doc = it.current(); QFileInfo fi( doc->file() ); if ( !fi.exists() ) continue; bool fake = !doc->linkFileKnown(); if ( !fake ) { QFile f( doc->linkFile() ); if ( f.open( IO_ReadOnly ) ) { QTextStream ts( &f ); ts.setEncoding( QTextStream::UnicodeUTF8 ); contents += ts.read(); f.close(); } else fake = TRUE; } if (fake) { contents += "[Desktop Entry]\n"; // No tr contents += "Categories = " + // No tr cats.labels("Document View",doc->categories()).join(";") + "\n"; // No tr contents += "Name = "+doc->name()+"\n"; // No tr contents += "Type = "+doc->type()+"\n"; // No tr } contents += "File = "+doc->file()+"\n"; // No tr // (resolves path) contents += QString("Size = %1\n").arg( fi.size() ); // No tr } //odebug << "sending length " << contents.length() << "" << oendl; #ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" ); e << contents; #endif //odebug << "================ \n\n" << contents << "\n\n===============" << oendl; d->needToSendAllDocLinks = false; } DocumentListPrivate::DocumentListPrivate( ServerInterface *gui ) { storage = new StorageInfo( this ); serverGui = gui; if ( serverGui ) { sendAppLnks = serverGui->requiresApplications(); sendDocLnks = serverGui->requiresDocuments(); } else { sendAppLnks = false; sendDocLnks = false; } for ( int i = 0; i < MAX_SEARCH_DEPTH; i++ ) { listDirs[i] = 0; lists[i] = 0; listPositions[i] = 0; } initialize(); tid = 0; } void DocumentListPrivate::appendDocpath(FileSystem*fs) { QDir defPath(fs->path()+"/Documents"); QFileInfo f(fs->path()+"/.opiestorage.cf"); if (!f.exists()) { Mediadlg dlg(fs); if (QDialog::Accepted != QPEApplication::execDialog( &dlg )) { return; } } Config conf(f.filePath(), Config::File ); conf.setGroup("main"); if (!conf.readBoolEntry("check",false)) { return; } conf.setGroup("subdirs"); bool read_all = conf.readBoolEntry("wholemedia",true); if (read_all) { docPaths+=fs->path(); return; } QStringList subDirs = conf.readListEntry("subdirs",':'); if (subDirs.isEmpty()) { if (defPath.exists()) { docPaths+=defPath.path(); } return; } for (unsigned c = 0; c < subDirs.count();++c) { QDir docDir(QString(fs->path()+"/"+subDirs[c])); if (docDir.exists()) { docPaths+=docDir.path(); } } } void DocumentListPrivate::initialize() { // Reset dls.clear(); docPaths.clear(); reference.clear(); QDir docDir( QPEApplication::documentDir() ); if ( docDir.exists() ) docPaths += QPEApplication::documentDir(); int i = 1; const QList<FileSystem> &fs = storage->fileSystems(); QListIterator<FileSystem> it( fs ); for ( ; it.current(); ++it ) { if ( (*it)->isRemovable() ) { appendDocpath((*it)); ++i; } } for ( int i = 0; i < MAX_SEARCH_DEPTH; ++i ) { if ( listDirs[i] ) { delete listDirs[i]; listDirs[i] = 0; } lists[i] = 0; listPositions[i] = 0; } docPathsSearched = 0; searchDepth = -1; state = Find; dit = 0; } DocumentListPrivate::~DocumentListPrivate() { for ( int i = 0; i < MAX_SEARCH_DEPTH; i++ ) if ( listDirs[i] ) delete listDirs[i]; delete dit; } void DocumentListPrivate::estimatedPercentScanned() { double overallProgress = 0.0; double levelWeight = 75.0; int topCount = docPaths.count(); if ( topCount > 1 ) { levelWeight = levelWeight / topCount; overallProgress += (docPathsSearched - 1) * levelWeight; } for ( int d = 0; d <= searchDepth; d++ ) { if ( listDirs[d] ) { int items = lists[d]->count(); if ( items > 1 ) { levelWeight = levelWeight / items; // Take in to account "." and ".." overallProgress += (listPositions[d] - 3) * levelWeight; } } else { break; } } // odebug << "overallProgress: " << overallProgress << "" << oendl; if ( serverGui ) serverGui->documentScanningProgress( (int)overallProgress ); } const QString DocumentListPrivate::nextFile() { while ( TRUE ) { while ( searchDepth < 0 ) { // go to next base path if ( docPathsSearched >= docPaths.count() ) { // end of base paths return QString::null; } else { QDir dir( docPaths[docPathsSearched] ); // odebug << "now using base path: " << docPaths[docPathsSearched] << "" << oendl; docPathsSearched++; if ( !dir.exists( ".Qtopia-ignore" ) ) { listDirs[0] = new QDir( dir ); lists[0] = listDirs[0]->entryInfoList(); listPositions[0] = 0; searchDepth = 0; } } } const QFileInfoList *fil = lists[searchDepth]; if (!fil) { return QString::null; } QFileInfoList *fl = (QFileInfoList *)fil; unsigned int pos = listPositions[searchDepth]; if ( pos >= fl->count() ) { // go up a depth delete listDirs[searchDepth]; listDirs[searchDepth] = 0; lists[searchDepth] = 0; listPositions[searchDepth] = 0; searchDepth--; } else { const QFileInfo *fi = fl->at(pos); listPositions[searchDepth]++; QString bn = fi->fileName(); if ( bn[0] != '.' ) { if ( fi->isDir() ) { if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" ) { // go down a depth QDir dir( fi->filePath() ); // odebug << "now going in to path: " << bn << "" << oendl; 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 @@ -1,1173 +1,1173 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ // Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED. #if defined(connect) #undef connect #endif #include "qprocess.h" /* OPIE */ #include <opie2/odebug.h> using namespace Opie::Core; /* QT */ #ifndef QT_NO_PROCESS #include <qapplication.h> #include <qqueue.h> #include <qlist.h> #include <qsocketnotifier.h> #include <qtimer.h> #include <qregexp.h> #include "qcleanuphandler_p.h" /* STD */ #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <sys/fcntl.h> #include <errno.h> #ifdef Q_OS_MACX #include <sys/time.h> #endif #include <sys/resource.h> #ifdef __MIPSEL__ # ifndef SOCK_DGRAM # define SOCK_DGRAM 1 # endif # ifndef SOCK_STREAM # define SOCK_STREAM 2 # endif #endif //#define QT_QPROCESS_DEBUG #ifdef Q_C_CALLBACKS extern "C" { #endif // Q_C_CALLBACKS #define QT_SIGNAL_RETTYPE void #define QT_SIGNAL_ARGS int #define QT_SIGNAL_IGNORE SIG_IGN QT_SIGNAL_RETTYPE qt_C_sigchldHnd(QT_SIGNAL_ARGS); QT_SIGNAL_RETTYPE qt_C_sigpipeHnd(QT_SIGNAL_ARGS); #ifdef Q_C_CALLBACKS } #endif // Q_C_CALLBACKS class QProc; class QProcessManager; class QProcessPrivate { public: QProcessPrivate(); ~QProcessPrivate(); void closeOpenSocketsForChild(); void newProc( pid_t pid, QProcess *process ); QByteArray bufStdout; QByteArray bufStderr; QQueue<QByteArray> stdinBuf; QSocketNotifier *notifierStdin; QSocketNotifier *notifierStdout; QSocketNotifier *notifierStderr; ssize_t stdinBufRead; QProc *proc; bool exitValuesCalculated; bool socketReadCalled; static QProcessManager *procManager; }; /*********************************************************************** * * QProc * **********************************************************************/ /* The class QProcess does not necessarily map exactly to the running child processes: if the process is finished, the QProcess class may still be there; furthermore a user can use QProcess to start more than one process. The helper-class QProc has the semantics that one instance of this class maps directly to a running child process. */ class QProc { public: QProc( pid_t p, QProcess *proc=0 ) : pid(p), process(proc) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProc: Constructor for pid " << pid << " and QProcess " << process << "" << oendl; #endif - socketStdin = 0; - socketStdout = 0; - socketStderr = 0; + socketStdin = 0; + socketStdout = 0; + socketStderr = 0; } ~QProc() { #if defined(QT_QPROCESS_DEBUG) odebug << "QProc: Destructor for pid " << pid << " and QProcess " << process << "" << oendl; #endif - if ( process != 0 ) { - if ( process->d->notifierStdin ) - process->d->notifierStdin->setEnabled( FALSE ); - if ( process->d->notifierStdout ) - process->d->notifierStdout->setEnabled( FALSE ); - if ( process->d->notifierStderr ) - process->d->notifierStderr->setEnabled( FALSE ); - process->d->proc = 0; - } - if( socketStdin != 0 ) - ::close( socketStdin ); - // ### close these sockets even on parent exit or is it better only on - // sigchld (but what do I have to do with them on exit then)? - if( socketStdout != 0 ) - ::close( socketStdout ); - if( socketStderr != 0 ) - ::close( socketStderr ); + if ( process != 0 ) { + if ( process->d->notifierStdin ) + process->d->notifierStdin->setEnabled( FALSE ); + if ( process->d->notifierStdout ) + process->d->notifierStdout->setEnabled( FALSE ); + if ( process->d->notifierStderr ) + process->d->notifierStderr->setEnabled( FALSE ); + process->d->proc = 0; + } + if( socketStdin != 0 ) + ::close( socketStdin ); + // ### close these sockets even on parent exit or is it better only on + // sigchld (but what do I have to do with them on exit then)? + if( socketStdout != 0 ) + ::close( socketStdout ); + if( socketStderr != 0 ) + ::close( socketStderr ); } pid_t pid; int socketStdin; int socketStdout; int socketStderr; QProcess *process; }; /*********************************************************************** * * QProcessManager * **********************************************************************/ class QProcessManager : public QObject { Q_OBJECT public: QProcessManager(); ~QProcessManager(); void append( QProc *p ); void remove( QProc *p ); void cleanup(); public slots: void removeMe(); void sigchldHnd( int ); public: struct sigaction oldactChld; struct sigaction oldactPipe; QList<QProc> *procList; int sigchldFd[2]; }; QCleanupHandler<QProcessManager> qprocess_cleanup_procmanager; QProcessManager::QProcessManager() { procList = new QList<QProc>; procList->setAutoDelete( TRUE ); // The SIGCHLD handler writes to a socket to tell the manager that // something happened. This is done to get the processing in sync with the // event reporting. if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) { - sigchldFd[0] = 0; - sigchldFd[1] = 0; + sigchldFd[0] = 0; + sigchldFd[1] = 0; } else { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: install socket notifier (" << sigchldFd[1] << ")" << oendl; #endif - QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1], - QSocketNotifier::Read, this ); - connect( sn, SIGNAL(activated(int)), - this, SLOT(sigchldHnd(int)) ); - sn->setEnabled( TRUE ); + QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1], + QSocketNotifier::Read, this ); + connect( sn, SIGNAL(activated(int)), + this, SLOT(sigchldHnd(int)) ); + sn->setEnabled( TRUE ); } // install a SIGCHLD handler and ignore SIGPIPE struct sigaction act; #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: install a SIGCHLD handler" << oendl; #endif act.sa_handler = qt_C_sigchldHnd; sigemptyset( &(act.sa_mask) ); sigaddset( &(act.sa_mask), SIGCHLD ); act.sa_flags = SA_NOCLDSTOP; #if defined(SA_RESTART) act.sa_flags |= SA_RESTART; #endif if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 ) owarn << "Error installing SIGCHLD handler" << oendl; #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: install a SIGPIPE handler (SIG_IGN)" << oendl; #endif /* - Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround - for a strange problem where GNU tar (called by backuprestore) - would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd - is never even called, yet this avoids the hang. + Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround + for a strange problem where GNU tar (called by backuprestore) + would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd + is never even called, yet this avoids the hang. */ act.sa_handler = qt_C_sigpipeHnd; sigemptyset( &(act.sa_mask) ); sigaddset( &(act.sa_mask), SIGPIPE ); act.sa_flags = 0; if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 ) owarn << "Error installing SIGPIPE handler" << oendl; } QProcessManager::~QProcessManager() { delete procList; if ( sigchldFd[0] != 0 ) - ::close( sigchldFd[0] ); + ::close( sigchldFd[0] ); if ( sigchldFd[1] != 0 ) - ::close( sigchldFd[1] ); + ::close( sigchldFd[1] ); // restore SIGCHLD handler #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: restore old sigchild handler" << oendl; #endif if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 ) owarn << "Error restoring SIGCHLD handler" << oendl; #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: restore old sigpipe handler" << oendl; #endif if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 ) owarn << "Error restoring SIGPIPE handler" << oendl; } void QProcessManager::append( QProc *p ) { procList->append( p ); #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: append process (procList.count(): " << procList->count() << ")" << oendl; #endif } void QProcessManager::remove( QProc *p ) { procList->remove( p ); #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager: remove process (procList.count(): " << procList->count() << ")" << oendl; #endif cleanup(); } void QProcessManager::cleanup() { if ( procList->count() == 0 ) { - QTimer::singleShot( 0, this, SLOT(removeMe()) ); + QTimer::singleShot( 0, this, SLOT(removeMe()) ); } } void QProcessManager::removeMe() { if ( procList->count() == 0 ) { - qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager ); - QProcessPrivate::procManager = 0; - delete this; + qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager ); + QProcessPrivate::procManager = 0; + delete this; } } void QProcessManager::sigchldHnd( int fd ) { char tmp; ::read( fd, &tmp, sizeof(tmp) ); #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager::sigchldHnd()" << oendl; #endif QProc *proc; QProcess *process; bool removeProc; proc = procList->first(); while ( proc != 0 ) { - removeProc = FALSE; - process = proc->process; - QProcess *process_exit_notify=0; - if ( process != 0 ) { - if ( !process->isRunning() ) { + removeProc = FALSE; + process = proc->process; + QProcess *process_exit_notify=0; + if ( process != 0 ) { + if ( !process->isRunning() ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess available)" << oendl; #endif - // read pending data - int nbytes = 0; - if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { + // read pending data + int nbytes = 0; + if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stdout" << oendl; #endif - process->socketRead( proc->socketStdout ); - } - nbytes = 0; - if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { + process->socketRead( proc->socketStdout ); + } + nbytes = 0; + if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stderr" << oendl; #endif - process->socketRead( proc->socketStderr ); - } + process->socketRead( proc->socketStderr ); + } - if ( process->notifyOnExit ) - process_exit_notify = process; + if ( process->notifyOnExit ) + process_exit_notify = process; - removeProc = TRUE; - } - } else { - int status; - if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { + removeProc = TRUE; + } + } else { + int status; + if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess not available)" << oendl; #endif - removeProc = TRUE; - } - } - if ( removeProc ) { - QProc *oldproc = proc; - proc = procList->next(); - remove( oldproc ); - } else { - proc = procList->next(); - } - if ( process_exit_notify ) - emit process_exit_notify->processExited(); + removeProc = TRUE; + } + } + if ( removeProc ) { + QProc *oldproc = proc; + proc = procList->next(); + remove( oldproc ); + } else { + proc = procList->next(); + } + if ( process_exit_notify ) + emit process_exit_notify->processExited(); } } #include "qprocess_unix.moc" /*********************************************************************** * * QProcessPrivate * **********************************************************************/ QProcessManager *QProcessPrivate::procManager = 0; QProcessPrivate::QProcessPrivate() { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessPrivate: Constructor" << oendl; #endif stdinBufRead = 0; notifierStdin = 0; notifierStdout = 0; notifierStderr = 0; exitValuesCalculated = FALSE; socketReadCalled = FALSE; proc = 0; } QProcessPrivate::~QProcessPrivate() { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcessPrivate: Destructor" << oendl; #endif if ( proc != 0 ) { - if ( proc->socketStdin != 0 ) { - ::close( proc->socketStdin ); - proc->socketStdin = 0; - } - proc->process = 0; + if ( proc->socketStdin != 0 ) { + ::close( proc->socketStdin ); + proc->socketStdin = 0; + } + proc->process = 0; } while ( !stdinBuf.isEmpty() ) { - delete stdinBuf.dequeue(); + delete stdinBuf.dequeue(); } delete notifierStdin; delete notifierStdout; delete notifierStderr; } /* Closes all open sockets in the child process that are not needed by the child process. Otherwise one child may have an open socket on standard input, etc. of another child. */ void QProcessPrivate::closeOpenSocketsForChild() { if ( procManager != 0 ) { - if ( procManager->sigchldFd[0] != 0 ) - ::close( procManager->sigchldFd[0] ); - if ( procManager->sigchldFd[1] != 0 ) - ::close( procManager->sigchldFd[1] ); - - // close also the sockets from other QProcess instances - QProc *proc; - for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) { - ::close( proc->socketStdin ); - ::close( proc->socketStdout ); - ::close( proc->socketStderr ); - } + if ( procManager->sigchldFd[0] != 0 ) + ::close( procManager->sigchldFd[0] ); + if ( procManager->sigchldFd[1] != 0 ) + ::close( procManager->sigchldFd[1] ); + + // close also the sockets from other QProcess instances + QProc *proc; + for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) { + ::close( proc->socketStdin ); + ::close( proc->socketStdout ); + ::close( proc->socketStderr ); + } } } void QProcessPrivate::newProc( pid_t pid, QProcess *process ) { proc = new QProc( pid, process ); if ( procManager == 0 ) { - procManager = new QProcessManager; - qprocess_cleanup_procmanager.add( &procManager ); + procManager = new QProcessManager; + qprocess_cleanup_procmanager.add( &procManager ); } // the QProcessManager takes care of deleting the QProc instances procManager->append( proc ); } /*********************************************************************** * * sigchld handler callback * **********************************************************************/ QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS ) { if ( QProcessPrivate::procManager == 0 ) - return; + return; if ( QProcessPrivate::procManager->sigchldFd[0] == 0 ) - return; + return; char a = 1; ::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ); } QT_SIGNAL_RETTYPE qt_C_sigpipeHnd( QT_SIGNAL_ARGS ) { // Ignore (but in a way somehow different to SIG_IGN). } /*********************************************************************** * * QProcess * **********************************************************************/ /*! This private class does basic initialization. */ void QProcess::init() { d = new QProcessPrivate(); exitStat = 0; exitNormal = FALSE; } /*! This private class resets the process variables, etc. so that it can be used for another process to start. */ void QProcess::reset() { delete d; d = new QProcessPrivate(); exitStat = 0; exitNormal = FALSE; d->bufStdout.resize( 0 ); d->bufStderr.resize( 0 ); } QByteArray* QProcess::bufStdout() { if ( d->proc && d->proc->socketStdout ) { - // ### can this cause a blocking behaviour (maybe do a ioctl() to see - // if data is available)? - socketRead( d->proc->socketStdout ); + // ### can this cause a blocking behaviour (maybe do a ioctl() to see + // if data is available)? + socketRead( d->proc->socketStdout ); } return &d->bufStdout; } QByteArray* QProcess::bufStderr() { if ( d->proc && d->proc->socketStderr ) { - // ### can this cause a blocking behaviour (maybe do a ioctl() to see - // if data is available)? - socketRead( d->proc->socketStderr ); + // ### can this cause a blocking behaviour (maybe do a ioctl() to see + // if data is available)? + socketRead( d->proc->socketStderr ); } return &d->bufStderr; } void QProcess::consumeBufStdout( int consume ) { uint n = d->bufStdout.size(); if ( consume==-1 || (uint)consume >= n ) { - d->bufStdout.resize( 0 ); + d->bufStdout.resize( 0 ); } else { - QByteArray tmp( n - consume ); - memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume ); - d->bufStdout = tmp; + QByteArray tmp( n - consume ); + memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume ); + d->bufStdout = tmp; } } void QProcess::consumeBufStderr( int consume ) { uint n = d->bufStderr.size(); if ( consume==-1 || (uint)consume >= n ) { - d->bufStderr.resize( 0 ); + d->bufStderr.resize( 0 ); } else { - QByteArray tmp( n - consume ); - memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume ); - d->bufStderr = tmp; + QByteArray tmp( n - consume ); + memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume ); + d->bufStderr = tmp; } } /*! Destroys the class. If the process is running, it is NOT terminated! Standard input, standard output and standard error of the process are closed. You can connect the destroyed() signal to the kill() slot, if you want the process to be terminated automatically when the class is destroyed. \sa tryTerminate() kill() */ QProcess::~QProcess() { delete d; } /*! Tries to run a process for the command and arguments that were specified with setArguments(), addArgument() or that were specified in the constructor. The command is searched in the path for executable programs; you can also use an absolute path to the command. If \a env is null, then the process is started with the same environment as the starting process. If \a env is non-null, then the values in the stringlist are interpreted as environment setttings of the form \c {key=value} and the process is started in these environment settings. For convenience, there is a small exception to this rule: under Unix, if \a env does not contain any settings for the environment variable \c LD_LIBRARY_PATH, then this variable is inherited from the starting process; under Windows the same applies for the enverionment varialbe \c PATH. Returns TRUE if the process could be started, otherwise FALSE. You can write data to standard input of the process with writeToStdin(), you can close standard input with closeStdin() and you can terminate the process tryTerminate() resp. kill(). You can call this function even when there already is a running process in this object. In this case, QProcess closes standard input of the old process and deletes pending data, i.e., you loose all control over that process, but the process is not terminated. This applies also if the process could not be started. (On operating systems that have zombie processes, Qt will also wait() on the old process.) \sa launch() closeStdin() */ bool QProcess::start( QStringList *env ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::start()" << oendl; #endif reset(); int sStdin[2]; int sStdout[2]; int sStderr[2]; // open sockets for piping if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) { - return FALSE; + return FALSE; } if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) { - return FALSE; + return FALSE; } if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) { - return FALSE; + return FALSE; } // the following pipe is only used to determine if the process could be // started int fd[2]; if ( pipe( fd ) < 0 ) { - // non critical error, go on - fd[0] = 0; - fd[1] = 0; + // non critical error, go on + fd[0] = 0; + fd[1] = 0; } // construct the arguments for exec QCString *arglistQ = new QCString[ _arguments.count() + 1 ]; const char** arglist = new const char*[ _arguments.count() + 1 ]; int i = 0; for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) { - arglistQ[i] = (*it).local8Bit(); - arglist[i] = arglistQ[i]; + arglistQ[i] = (*it).local8Bit(); + arglist[i] = arglistQ[i]; #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::start(): arg " << i << " = " << arglist[i] << "" << oendl; #endif - i++; + i++; } arglist[i] = 0; // Must make sure signal handlers are installed before exec'ing // in case the process exits quickly. if ( d->procManager == 0 ) { - d->procManager = new QProcessManager; - qprocess_cleanup_procmanager.add( &d->procManager ); + d->procManager = new QProcessManager; + qprocess_cleanup_procmanager.add( &d->procManager ); } // fork and exec QApplication::flushX(); pid_t pid = fork(); if ( pid == 0 ) { - // child - d->closeOpenSocketsForChild(); - if ( comms & Stdin ) { - ::close( sStdin[1] ); - ::dup2( sStdin[0], STDIN_FILENO ); - } - if ( comms & Stdout ) { - ::close( sStdout[0] ); - ::dup2( sStdout[1], STDOUT_FILENO ); - } - if ( comms & Stderr ) { - ::close( sStderr[0] ); - ::dup2( sStderr[1], STDERR_FILENO ); - } - if ( comms & DupStderr ) { - ::dup2( STDOUT_FILENO, STDERR_FILENO ); - } + // child + d->closeOpenSocketsForChild(); + if ( comms & Stdin ) { + ::close( sStdin[1] ); + ::dup2( sStdin[0], STDIN_FILENO ); + } + if ( comms & Stdout ) { + ::close( sStdout[0] ); + ::dup2( sStdout[1], STDOUT_FILENO ); + } + if ( comms & Stderr ) { + ::close( sStderr[0] ); + ::dup2( sStderr[1], STDERR_FILENO ); + } + if ( comms & DupStderr ) { + ::dup2( STDOUT_FILENO, STDERR_FILENO ); + } #ifndef QT_NO_DIR - ::chdir( workingDir.absPath().latin1() ); + ::chdir( workingDir.absPath().latin1() ); #endif - if ( fd[0] ) - ::close( fd[0] ); - if ( fd[1] ) - ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess - - if ( env == 0 ) { // inherit environment and start process - ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice - } else { // start process with environment settins as specified in env - // construct the environment for exec - int numEntries = env->count(); - bool setLibraryPath = - env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() && - getenv( "LD_LIBRARY_PATH" ) != 0; - if ( setLibraryPath ) - numEntries++; - QCString *envlistQ = new QCString[ numEntries + 1 ]; - const char** envlist = new const char*[ numEntries + 1 ]; - int i = 0; - if ( setLibraryPath ) { - envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit(); - envlist[i] = envlistQ[i]; - i++; - } - for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { - envlistQ[i] = (*it).local8Bit(); - envlist[i] = envlistQ[i]; - i++; - } - envlist[i] = 0; - - // look for the executable in the search path - if ( _arguments.count()>0 && getenv("PATH")!=0 ) { - QString command = _arguments[0]; - if ( !command.contains( '/' ) ) { - QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); - for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { - QString dir = *it; + if ( fd[0] ) + ::close( fd[0] ); + if ( fd[1] ) + ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess + + if ( env == 0 ) { // inherit environment and start process + ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice + } else { // start process with environment settins as specified in env + // construct the environment for exec + int numEntries = env->count(); + bool setLibraryPath = + env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() && + getenv( "LD_LIBRARY_PATH" ) != 0; + if ( setLibraryPath ) + numEntries++; + QCString *envlistQ = new QCString[ numEntries + 1 ]; + const char** envlist = new const char*[ numEntries + 1 ]; + int i = 0; + if ( setLibraryPath ) { + envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit(); + envlist[i] = envlistQ[i]; + i++; + } + for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { + envlistQ[i] = (*it).local8Bit(); + envlist[i] = envlistQ[i]; + i++; + } + envlist[i] = 0; + + // look for the executable in the search path + if ( _arguments.count()>0 && getenv("PATH")!=0 ) { + QString command = _arguments[0]; + if ( !command.contains( '/' ) ) { + QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); + for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { + QString dir = *it; #ifdef Q_OS_MACX - if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle - dir += "/" + command + ".app/Contents/MacOS"; + if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle + dir += "/" + command + ".app/Contents/MacOS"; #endif #ifndef QT_NO_DIR - QFileInfo fileInfo( dir, command ); + QFileInfo fileInfo( dir, command ); #else - QFileInfo fileInfo( dir + "/" + command ); + QFileInfo fileInfo( dir + "/" + command ); #endif - if ( fileInfo.isExecutable() ) { - arglistQ[0] = fileInfo.filePath().local8Bit(); - arglist[0] = arglistQ[0]; - break; - } - } - } - } - ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice - } - if ( fd[1] ) { - char buf = 0; - ::write( fd[1], &buf, 1 ); - ::close( fd[1] ); - } - ::exit( -1 ); + if ( fileInfo.isExecutable() ) { + arglistQ[0] = fileInfo.filePath().local8Bit(); + arglist[0] = arglistQ[0]; + break; + } + } + } + } + ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice + } + if ( fd[1] ) { + char buf = 0; + ::write( fd[1], &buf, 1 ); + ::close( fd[1] ); + } + ::exit( -1 ); } else if ( pid == -1 ) { - // error forking - goto error; + // error forking + goto error; } // test if exec was successful if ( fd[1] ) - ::close( fd[1] ); + ::close( fd[1] ); if ( fd[0] ) { - char buf; - for ( ;; ) { - int n = ::read( fd[0], &buf, 1 ); - if ( n==1 ) { - // socket was not closed => error - d->proc = 0; - goto error; - } else if ( n==-1 ) { - if ( errno==EAGAIN || errno==EINTR ) - // try it again - continue; - } - break; - } - ::close( fd[0] ); + char buf; + for ( ;; ) { + int n = ::read( fd[0], &buf, 1 ); + if ( n==1 ) { + // socket was not closed => error + d->proc = 0; + goto error; + } else if ( n==-1 ) { + if ( errno==EAGAIN || errno==EINTR ) + // try it again + continue; + } + break; + } + ::close( fd[0] ); } d->newProc( pid, this ); if ( comms & Stdin ) { - ::close( sStdin[0] ); - d->proc->socketStdin = sStdin[1]; - d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); - connect( d->notifierStdin, SIGNAL(activated(int)), - this, SLOT(socketWrite(int)) ); - // setup notifiers for the sockets - if ( !d->stdinBuf.isEmpty() ) { - d->notifierStdin->setEnabled( TRUE ); - } + ::close( sStdin[0] ); + d->proc->socketStdin = sStdin[1]; + d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); + connect( d->notifierStdin, SIGNAL(activated(int)), + this, SLOT(socketWrite(int)) ); + // setup notifiers for the sockets + if ( !d->stdinBuf.isEmpty() ) { + d->notifierStdin->setEnabled( TRUE ); + } } if ( comms & Stdout ) { - ::close( sStdout[1] ); - d->proc->socketStdout = sStdout[0]; - d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); - connect( d->notifierStdout, SIGNAL(activated(int)), - this, SLOT(socketRead(int)) ); - if ( ioRedirection ) - d->notifierStdout->setEnabled( TRUE ); + ::close( sStdout[1] ); + d->proc->socketStdout = sStdout[0]; + d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); + connect( d->notifierStdout, SIGNAL(activated(int)), + this, SLOT(socketRead(int)) ); + if ( ioRedirection ) + d->notifierStdout->setEnabled( TRUE ); } if ( comms & Stderr ) { - ::close( sStderr[1] ); - d->proc->socketStderr = sStderr[0]; - d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); - connect( d->notifierStderr, SIGNAL(activated(int)), - this, SLOT(socketRead(int)) ); - if ( ioRedirection ) - d->notifierStderr->setEnabled( TRUE ); + ::close( sStderr[1] ); + d->proc->socketStderr = sStderr[0]; + d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); + connect( d->notifierStderr, SIGNAL(activated(int)), + this, SLOT(socketRead(int)) ); + if ( ioRedirection ) + d->notifierStderr->setEnabled( TRUE ); } // cleanup and return delete[] arglistQ; delete[] arglist; return TRUE; error: #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::start(): error starting process" << oendl; #endif if ( d->procManager ) - d->procManager->cleanup(); + d->procManager->cleanup(); if ( comms & Stdin ) { - ::close( sStdin[1] ); - ::close( sStdin[0] ); + ::close( sStdin[1] ); + ::close( sStdin[0] ); } if ( comms & Stdout ) { - ::close( sStdout[0] ); - ::close( sStdout[1] ); + ::close( sStdout[0] ); + ::close( sStdout[1] ); } if ( comms & Stderr ) { - ::close( sStderr[0] ); - ::close( sStderr[1] ); + ::close( sStderr[0] ); + ::close( sStderr[1] ); } ::close( fd[0] ); ::close( fd[1] ); delete[] arglistQ; delete[] arglist; return FALSE; } /*! Asks the process to terminate. Processes can ignore this wish. If you want to be sure that the process really terminates, you must use kill() instead. The slot returns immediately: it does not wait until the process has finished. When the process really exited, the signal processExited() is emitted. \sa kill() processExited() */ void QProcess::tryTerminate() const { if ( d->proc != 0 ) - ::kill( d->proc->pid, SIGTERM ); + ::kill( d->proc->pid, SIGTERM ); } /*! Terminates the process. This is not a safe way to end a process since the process will not be able to do cleanup. tryTerminate() is a safer way to do it, but processes might ignore a tryTerminate(). The nice way to end a process and to be sure that it is finished, is doing something like this: \code process->tryTerminate(); QTimer::singleShot( 5000, process, SLOT( kill() ) ); \endcode This tries to terminate the process the nice way. If the process is still running after 5 seconds, it terminates the process the hard way. The timeout should be chosen depending on the time the process needs to do all the cleanup: use a higher value if the process is likely to do heavy computation on cleanup. The slot returns immediately: it does not wait until the process has finished. When the process really exited, the signal processExited() is emitted. \sa tryTerminate() processExited() */ void QProcess::kill() const { if ( d->proc != 0 ) - ::kill( d->proc->pid, SIGKILL ); + ::kill( d->proc->pid, SIGKILL ); } /*! Returns TRUE if the process is running, otherwise FALSE. \sa normalExit() exitStatus() processExited() */ bool QProcess::isRunning() const { if ( d->exitValuesCalculated ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::isRunning(): FALSE (already computed)" << oendl; #endif - return FALSE; + return FALSE; } if ( d->proc == 0 ) - return FALSE; + return FALSE; int status; if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) { - // compute the exit values - QProcess *that = (QProcess*)this; // mutable - that->exitNormal = WIFEXITED( status ) != 0; - if ( exitNormal ) { - that->exitStat = (char)WEXITSTATUS( status ); - } - d->exitValuesCalculated = TRUE; + // compute the exit values + QProcess *that = (QProcess*)this; // mutable + that->exitNormal = WIFEXITED( status ) != 0; + if ( exitNormal ) { + that->exitStat = (char)WEXITSTATUS( status ); + } + d->exitValuesCalculated = TRUE; #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): FALSE" << oendl; #endif - return FALSE; + return FALSE; } #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): TRUE" << oendl; #endif return TRUE; } /*! Writes the data \a buf to the standard input of the process. The process may or may not read this data. This function returns immediately; the QProcess class might write the data at a later point (you have to enter the event loop for that). When all the data is written to the process, the signal wroteToStdin() is emitted. This does not mean that the process really read the data, since this class only detects when it was able to write the data to the operating system. \sa wroteToStdin() closeStdin() readStdout() readStderr() */ void QProcess::writeToStdin( const QByteArray& buf ) { #if defined(QT_QPROCESS_DEBUG) // odebug << "QProcess::writeToStdin(): write to stdin (" << d->socketStdin << ")" << oendl; #endif d->stdinBuf.enqueue( new QByteArray(buf) ); if ( d->notifierStdin != 0 ) - d->notifierStdin->setEnabled( TRUE ); + d->notifierStdin->setEnabled( TRUE ); } /*! Closes standard input of the process. This function also deletes pending data that is not written to standard input yet. \sa wroteToStdin() */ void QProcess::closeStdin() { if ( d->proc == 0 ) - return; + return; if ( d->proc->socketStdin !=0 ) { - while ( !d->stdinBuf.isEmpty() ) { - delete d->stdinBuf.dequeue(); - } - delete d->notifierStdin; - d->notifierStdin = 0; - if ( ::close( d->proc->socketStdin ) != 0 ) { + while ( !d->stdinBuf.isEmpty() ) { + delete d->stdinBuf.dequeue(); + } + delete d->notifierStdin; + d->notifierStdin = 0; + if ( ::close( d->proc->socketStdin ) != 0 ) { owarn << "Could not close stdin of child process" << oendl; - } + } #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::closeStdin(): stdin (" << d->proc->socketStdin << ") closed" << oendl; #endif - d->proc->socketStdin = 0; + d->proc->socketStdin = 0; } } /* This private slot is called when the process has outputted data to either standard output or standard error. */ void QProcess::socketRead( int fd ) { if ( d->socketReadCalled ) { - // the slots that are connected to the readyRead...() signals might - // trigger a recursive call of socketRead(). Avoid this since you get a - // blocking read otherwise. - return; + // the slots that are connected to the readyRead...() signals might + // trigger a recursive call of socketRead(). Avoid this since you get a + // blocking read otherwise. + return; } #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::socketRead(): " << fd << "" << oendl; #endif if ( fd == 0 ) - return; + return; const int bufsize = 4096; QByteArray *buffer = 0; uint oldSize; int n; if ( fd == d->proc->socketStdout ) { - buffer = &d->bufStdout; + buffer = &d->bufStdout; } else if ( fd == d->proc->socketStderr ) { - buffer = &d->bufStderr; + buffer = &d->bufStderr; } else { - // this case should never happen, but just to be safe - return; + // this case should never happen, but just to be safe + return; } // read data oldSize = buffer->size(); buffer->resize( oldSize + bufsize ); n = ::read( fd, buffer->data()+oldSize, bufsize ); if ( n > 0 ) - buffer->resize( oldSize + n ); + buffer->resize( oldSize + n ); else - buffer->resize( oldSize ); + buffer->resize( oldSize ); // eof or error? if ( n == 0 || n == -1 ) { - if ( fd == d->proc->socketStdout ) { + if ( fd == d->proc->socketStdout ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::socketRead(): stdout (" << fd << ") closed" << oendl; #endif - d->notifierStdout->setEnabled( FALSE ); - delete d->notifierStdout; - d->notifierStdout = 0; - ::close( d->proc->socketStdout ); - d->proc->socketStdout = 0; - return; - } else if ( fd == d->proc->socketStderr ) { + d->notifierStdout->setEnabled( FALSE ); + delete d->notifierStdout; + d->notifierStdout = 0; + ::close( d->proc->socketStdout ); + d->proc->socketStdout = 0; + return; + } else if ( fd == d->proc->socketStderr ) { #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::socketRead(): stderr (" << fd << ") closed" << oendl; #endif - d->notifierStderr->setEnabled( FALSE ); - delete d->notifierStderr; - d->notifierStderr = 0; - ::close( d->proc->socketStderr ); - d->proc->socketStderr = 0; - return; - } + d->notifierStderr->setEnabled( FALSE ); + delete d->notifierStderr; + d->notifierStderr = 0; + ::close( d->proc->socketStderr ); + d->proc->socketStderr = 0; + return; + } } // read all data that is available while ( n == bufsize ) { - oldSize = buffer->size(); - buffer->resize( oldSize + bufsize ); - n = ::read( fd, buffer->data()+oldSize, bufsize ); - if ( n > 0 ) - buffer->resize( oldSize + n ); - else - buffer->resize( oldSize ); + oldSize = buffer->size(); + buffer->resize( oldSize + bufsize ); + n = ::read( fd, buffer->data()+oldSize, bufsize ); + if ( n > 0 ) + buffer->resize( oldSize + n ); + else + buffer->resize( oldSize ); } d->socketReadCalled = TRUE; if ( fd == d->proc->socketStdout ) { #if defined(QT_QPROCESS_DEBUG) - qDebug( "QProcess::socketRead(): %d bytes read from stdout (%d)", - buffer->size()-oldSize, fd ); + odebug << "QProcess::socketRead(): " << buffer->size()-oldSize << "bytes read from stdout (" + << fd << ")" << oendl; #endif - emit readyReadStdout(); + emit readyReadStdout(); } else if ( fd == d->proc->socketStderr ) { #if defined(QT_QPROCESS_DEBUG) - qDebug( "QProcess::socketRead(): %d bytes read from stderr (%d)", - buffer->size()-oldSize, fd ); + odebug << "QProcess::socketRead(): " << buffer->size()-oldSize << " bytes read from stderr (" + << fd << ")" << oendl; #endif - emit readyReadStderr(); + emit readyReadStderr(); } d->socketReadCalled = FALSE; } /* This private slot is called when the process tries to read data from standard input. */ void QProcess::socketWrite( int fd ) { if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 ) - return; + return; if ( d->stdinBuf.isEmpty() ) { - d->notifierStdin->setEnabled( FALSE ); - return; + d->notifierStdin->setEnabled( FALSE ); + return; } #if defined(QT_QPROCESS_DEBUG) odebug << "QProcess::socketWrite(): write to stdin (" << fd << ")" << oendl; #endif ssize_t ret = ::write( fd, - d->stdinBuf.head()->data() + d->stdinBufRead, - d->stdinBuf.head()->size() - d->stdinBufRead ); + d->stdinBuf.head()->data() + d->stdinBufRead, + d->stdinBuf.head()->size() - d->stdinBufRead ); if ( ret > 0 ) - d->stdinBufRead += ret; + d->stdinBufRead += ret; if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) { - d->stdinBufRead = 0; - delete d->stdinBuf.dequeue(); - if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) - emit wroteToStdin(); - socketWrite( fd ); + d->stdinBufRead = 0; + delete d->stdinBuf.dequeue(); + if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) + emit wroteToStdin(); + socketWrite( fd ); } } /*! \internal Flushes standard input. This is useful if you want to use QProcess in a synchronous manner. This function should probably go into the public API. */ void QProcess::flushStdin() { socketWrite( d->proc->socketStdin ); } /* This private slot is only used under Windows (but moc does not know about #if defined()). */ void QProcess::timeout() { } /* This private function is used by connectNotify() and disconnectNotify() to change the value of ioRedirection (and related behaviour) */ void QProcess::setIoRedirection( bool value ) { ioRedirection = value; if ( ioRedirection ) { - if ( d->notifierStdout ) - d->notifierStdout->setEnabled( TRUE ); - if ( d->notifierStderr ) - d->notifierStderr->setEnabled( TRUE ); + if ( d->notifierStdout ) + d->notifierStdout->setEnabled( TRUE ); + if ( d->notifierStderr ) + d->notifierStderr->setEnabled( TRUE ); } else { - if ( d->notifierStdout ) - d->notifierStdout->setEnabled( FALSE ); - if ( d->notifierStderr ) - d->notifierStderr->setEnabled( FALSE ); + if ( d->notifierStdout ) + d->notifierStdout->setEnabled( FALSE ); + if ( d->notifierStderr ) + d->notifierStderr->setEnabled( FALSE ); } } /* This private function is used by connectNotify() and disconnectNotify() to change the value of notifyOnExit (and related behaviour) */ void QProcess::setNotifyOnExit( bool value ) { notifyOnExit = value; } /* This private function is used by connectNotify() and disconnectNotify() to change the value of wroteToStdinConnected (and related behaviour) */ void QProcess::setWroteStdinConnected( bool value ) { wroteToStdinConnected = value; } /*! \enum QProcess::PID \internal */ /*! Returns platform dependent information about the process. This can be used together with platform specific system calls. Under Unix the return value is the PID of the process, or -1 if no process is belonging to this object. Under Windows it is a pointer to the \c PROCESS_INFORMATION struct, or 0 if no process is belonging to this object. */ QProcess::PID QProcess::processIdentifier() { if ( d->proc == 0 ) - return -1; + return -1; return d->proc->pid; } int QProcess::priority() const { if ( d->proc ) - return getpriority(PRIO_PROCESS,d->proc->pid); + return getpriority(PRIO_PROCESS,d->proc->pid); return 0; } void QProcess::setPriority(int p) { if ( d->proc ) - setpriority(PRIO_PROCESS,d->proc->pid,p); + setpriority(PRIO_PROCESS,d->proc->pid,p); } #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 @@ #include "screensaver.h" #include <qpe/config.h> #include <qpe/network.h> #include <opie2/odevice.h> +#include <opie2/odebug.h> using namespace Opie::Core; OpieScreenSaver::OpieScreenSaver ( ) - : QObject ( 0, "screensaver" ), QWSScreenSaver ( ) + : QObject ( 0, "screensaver" ), QWSScreenSaver ( ) { - m_disable_suspend = 100; - m_enable_dim = false; - m_enable_lightoff = false; - m_enable_suspend = false; - m_onlylcdoff = false; + m_disable_suspend = 100; + m_enable_dim = false; + m_enable_lightoff = false; + m_enable_suspend = false; + m_onlylcdoff = false; - m_enable_dim_ac = false; - m_enable_lightoff_ac = false; - m_enable_suspend_ac = false; - m_onlylcdoff_ac = false; + m_enable_dim_ac = false; + m_enable_lightoff_ac = false; + m_enable_suspend_ac = false; + m_onlylcdoff_ac = false; - m_use_light_sensor = false; - m_backlight_sensor = -1; - ::memset ( m_sensordata, 0xff, LS_Count * sizeof( m_sensordata [0] )); + m_use_light_sensor = false; + m_backlight_sensor = -1; + ::memset ( m_sensordata, 0xff, LS_Count * sizeof( m_sensordata [0] )); - m_lcd_status = true; + m_lcd_status = true; - m_backlight_normal = -1; - m_backlight_current = -1; - m_backlight_forcedoff = false; + m_backlight_normal = -1; + m_backlight_current = -1; + m_backlight_forcedoff = false; - m_on_ac = false; + m_on_ac = false; - m_level = -1; + m_level = -1; - // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off) - ODevice::inst ( )-> setDisplayStatus ( true ); - setBacklight ( -1 ); + // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off) + ODevice::inst ( )-> setDisplayStatus ( true ); + setBacklight ( -1 ); } /** * Stops the screen saver */ void OpieScreenSaver::restore() { - m_level = -1; + m_level = -1; - if ( !m_lcd_status ) { // We must have turned it off - ODevice::inst ( ) -> setDisplayStatus ( true ); - m_lcd_status = true; - } + if ( !m_lcd_status ) { // We must have turned it off + ODevice::inst ( ) -> setDisplayStatus ( true ); + m_lcd_status = true; + } - setBacklightInternal ( -1 ); + setBacklightInternal ( -1 ); } /** * Starts the screen saver * * @param level what level of screen saving should happen (0=lowest non-off, 1=off, * 2=suspend whole machine) * @returns true on success */ bool OpieScreenSaver::save( int level ) { - m_level = level; - - switch ( level ) { - case 0: - if (( m_on_ac && m_enable_dim_ac ) || - ( !m_on_ac && m_enable_dim )) { - if (( m_disable_suspend > 0 ) && ( m_backlight_current > 1 ) && !m_use_light_sensor ) - setBacklightInternal ( 1 ); // lowest non-off - } - return true; - break; - - case 1: - if (( m_on_ac && m_enable_lightoff_ac ) || - ( !m_on_ac && m_enable_lightoff )) { - if ( m_disable_suspend > 1 ) - setBacklightInternal ( 0 ); // off - } - return true; - break; - - case 2: - if (( m_on_ac && !m_enable_suspend_ac ) || - ( !m_on_ac && !m_enable_suspend )) { - return true; - } - - if (( m_on_ac && m_onlylcdoff_ac ) || - ( !m_on_ac && m_onlylcdoff )) { - ODevice::inst ( ) -> setDisplayStatus ( false ); - m_lcd_status = false; - return true; - } - - // We're going to suspend the whole machine - - if (( m_disable_suspend > 2 ) && !Network::networkOnline ( )) { - // TODO: why is this key F34 hard coded? -- schurig - // Does this now only work an devices with a ODevice::filter? - QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); - return true; - } - - break; - } - return false; + m_level = level; + + switch ( level ) { + case 0: + if (( m_on_ac && m_enable_dim_ac ) || + ( !m_on_ac && m_enable_dim )) { + if (( m_disable_suspend > 0 ) && ( m_backlight_current > 1 ) && !m_use_light_sensor ) + setBacklightInternal ( 1 ); // lowest non-off + } + return true; + break; + + case 1: + if (( m_on_ac && m_enable_lightoff_ac ) || + ( !m_on_ac && m_enable_lightoff )) { + if ( m_disable_suspend > 1 ) + setBacklightInternal ( 0 ); // off + } + return true; + break; + + case 2: + if (( m_on_ac && !m_enable_suspend_ac ) || + ( !m_on_ac && !m_enable_suspend )) { + return true; + } + + if (( m_on_ac && m_onlylcdoff_ac ) || + ( !m_on_ac && m_onlylcdoff )) { + ODevice::inst ( ) -> setDisplayStatus ( false ); + m_lcd_status = false; + return true; + } + + // We're going to suspend the whole machine + + if (( m_disable_suspend > 2 ) && !Network::networkOnline ( )) { + // TODO: why is this key F34 hard coded? -- schurig + // Does this now only work an devices with a ODevice::filter? + QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); + return true; + } + + break; + } + return false; } /** * Set intervals in seconds for automatic dimming, light off and suspend * * This function also sets the member variables m_m_enable_dim[_ac], * m_enable_lightoff[_ac], m_enable_suspend[_ac], m_onlylcdoff[_ac] * * @param dim time in seconds to dim, -1 to read value from config file, * 0 to disable * @param lightoff time in seconds to turn LCD backlight off, -1 to * read value from config file, 0 to disable * @param suspend time in seconds to do an APM suspend, -1 to * read value from config file, 0 to disable */ void OpieScreenSaver::setIntervals ( int dim, int lightoff, int suspend ) { - Config config ( "apm" ); - config. setGroup ( m_on_ac ? "AC" : "Battery" ); - - int v[ 4 ]; - if ( dim < 0 ) - dim = config. readNumEntry ( "Dim", m_on_ac ? 60 : 30 ); - if ( lightoff < 0 ) - lightoff = config. readNumEntry ( "LightOff", m_on_ac ? 120 : 20 ); - if ( suspend < 0 ) - suspend = config. readNumEntry ( "Suspend", m_on_ac ? 0 : 60 ); - - if ( m_on_ac ) { - m_enable_dim_ac = ( dim > 0 ); - m_enable_lightoff_ac = ( lightoff > 0 ); - m_enable_suspend_ac = ( suspend > 0 ); - m_onlylcdoff_ac = config.readBoolEntry ( "LcdOffOnly", false ); - } - else { - m_enable_dim = ( dim > 0 ); - m_enable_lightoff = ( lightoff > 0 ); - m_enable_suspend = ( suspend > 0 ); - m_onlylcdoff = config.readBoolEntry ( "LcdOffOnly", false ); - } - - //odebug << "screen saver intervals: " << dim << " " << lightoff << " " << suspend << "" << oendl; - - v [ 0 ] = QMAX( 1000 * dim, 100 ); - v [ 1 ] = QMAX( 1000 * lightoff, 100 ); - v [ 2 ] = QMAX( 1000 * suspend, 100 ); - v [ 3 ] = 0; - - if ( !dim && !lightoff && !suspend ) - QWSServer::setScreenSaverInterval( 0 ); - else - QWSServer::setScreenSaverIntervals( v ); + Config config ( "apm" ); + config. setGroup ( m_on_ac ? "AC" : "Battery" ); + + int v[ 4 ]; + if ( dim < 0 ) + dim = config. readNumEntry ( "Dim", m_on_ac ? 60 : 30 ); + if ( lightoff < 0 ) + lightoff = config. readNumEntry ( "LightOff", m_on_ac ? 120 : 20 ); + if ( suspend < 0 ) + suspend = config. readNumEntry ( "Suspend", m_on_ac ? 0 : 60 ); + + if ( m_on_ac ) { + m_enable_dim_ac = ( dim > 0 ); + m_enable_lightoff_ac = ( lightoff > 0 ); + m_enable_suspend_ac = ( suspend > 0 ); + m_onlylcdoff_ac = config.readBoolEntry ( "LcdOffOnly", false ); + } + else { + m_enable_dim = ( dim > 0 ); + m_enable_lightoff = ( lightoff > 0 ); + m_enable_suspend = ( suspend > 0 ); + m_onlylcdoff = config.readBoolEntry ( "LcdOffOnly", false ); + } + + //odebug << "screen saver intervals: " << dim << " " << lightoff << " " << suspend << "" << oendl; + + v [ 0 ] = QMAX( 1000 * dim, 100 ); + v [ 1 ] = QMAX( 1000 * lightoff, 100 ); + v [ 2 ] = QMAX( 1000 * suspend, 100 ); + v [ 3 ] = 0; + + if ( !dim && !lightoff && !suspend ) + QWSServer::setScreenSaverInterval( 0 ); + else + QWSServer::setScreenSaverIntervals( v ); } /** * Set suspend time. Will read the dim and lcd-off times from the config file. * * @param suspend time in seconds to go into APM suspend, -1 to * read value from config file, 0 to disable */ void OpieScreenSaver::setInterval ( int interval ) { - setIntervals ( -1, -1, interval ); + setIntervals ( -1, -1, interval ); } void OpieScreenSaver::setMode ( int mode ) { - if ( mode > m_disable_suspend ) - setInterval ( -1 ); - m_disable_suspend = mode; + if ( mode > m_disable_suspend ) + setInterval ( -1 ); + m_disable_suspend = mode; } /** * Set display brightness * * Get's default values for backlight, contrast and light sensor from config file. * * @param bright desired brighness (-1 to use automatic sensor data or value * from config file, -2 to toggle backlight on and off, -3 to * force backlight off) */ void OpieScreenSaver::setBacklight ( int bright ) { - // Read from config - Config config ( "apm" ); - config. setGroup ( m_on_ac ? "AC" : "Battery" ); - m_backlight_normal = config. readNumEntry ( "Brightness", m_on_ac ? 255 : 127 ); - int contrast = config. readNumEntry ( "Contrast", 127); - m_use_light_sensor = config. readBoolEntry ( "LightSensor", false ); - - //qDebug ( "setBacklight: %d (norm: %d) (ls: %d)", bright, m_backlight_normal, m_use_light_sensor ? 1 : 0 ); - - killTimers ( ); - if (( bright < 0 ) && m_use_light_sensor ) { - QStringList sl = config. readListEntry ( "LightSensorData", ';' ); - - m_sensordata [LS_SensorMin] = 40; - m_sensordata [LS_SensorMax] = 215; - m_sensordata [LS_LightMin] = 1; - m_sensordata [LS_LightMax] = 255; - m_sensordata [LS_Steps] = 12; - m_sensordata [LS_Interval] = 2000; - - for ( uint i = 0; i < LS_Count; i++ ) { - if ( i < sl. count ( )) - m_sensordata [i] = sl [i]. toInt ( ); - } - if ( m_sensordata [LS_Steps] < 2 ) // sanity check to avoid SIGFPE - m_sensordata [LS_Steps] = 2; - - timerEvent ( 0 ); - startTimer ( m_sensordata [LS_Interval] ); - } - - setBacklightInternal ( bright ); - ODevice::inst ( )-> setDisplayContrast(contrast); + // Read from config + Config config ( "apm" ); + config. setGroup ( m_on_ac ? "AC" : "Battery" ); + m_backlight_normal = config. readNumEntry ( "Brightness", m_on_ac ? 255 : 127 ); + int contrast = config. readNumEntry ( "Contrast", 127); + m_use_light_sensor = config. readBoolEntry ( "LightSensor", false ); + + //odebug << "setBacklight: " << bright << " (norm: " << m_backlight_normal << ") (ls: " + // << ( m_use_light_sensor ? 1 : 0 ) << ")" << oendl; + + killTimers ( ); + if (( bright < 0 ) && m_use_light_sensor ) { + QStringList sl = config. readListEntry ( "LightSensorData", ';' ); + + m_sensordata [LS_SensorMin] = 40; + m_sensordata [LS_SensorMax] = 215; + m_sensordata [LS_LightMin] = 1; + m_sensordata [LS_LightMax] = 255; + m_sensordata [LS_Steps] = 12; + m_sensordata [LS_Interval] = 2000; + + for ( uint i = 0; i < LS_Count; i++ ) { + if ( i < sl. count ( )) + m_sensordata [i] = sl [i]. toInt ( ); + } + if ( m_sensordata [LS_Steps] < 2 ) // sanity check to avoid SIGFPE + m_sensordata [LS_Steps] = 2; + + timerEvent ( 0 ); + startTimer ( m_sensordata [LS_Interval] ); + } + + setBacklightInternal ( bright ); + ODevice::inst ( )-> setDisplayContrast(contrast); } /** * Internal brightness setting method * * Get's default values for backlight and light sensor from config file. * * @param bright desired brighness (-1 to use automatic sensor data or value * from config file, -2 to toggle backlight on and off, -3 to * force backlight off) */ void OpieScreenSaver::setBacklightInternal ( int bright ) { - if ( bright == -3 ) { - // Forced on - m_backlight_forcedoff = false; - bright = -1; - } - if ( m_backlight_forcedoff && bright != -2 ) - return ; - if ( bright == -2 ) { - // Toggle between off and on - bright = m_backlight_current ? 0 : -1; - m_backlight_forcedoff = !bright; - } - if ( bright == -1 ) - bright = m_use_light_sensor ? m_backlight_sensor : m_backlight_normal; - - if ( bright != m_backlight_current ) { - ODevice::inst ( )-> setDisplayBrightness ( bright ); - m_backlight_current = bright; - } + if ( bright == -3 ) { + // Forced on + m_backlight_forcedoff = false; + bright = -1; + } + if ( m_backlight_forcedoff && bright != -2 ) + return ; + if ( bright == -2 ) { + // Toggle between off and on + bright = m_backlight_current ? 0 : -1; + m_backlight_forcedoff = !bright; + } + if ( bright == -1 ) + bright = m_use_light_sensor ? m_backlight_sensor : m_backlight_normal; + + if ( bright != m_backlight_current ) { + ODevice::inst ( )-> setDisplayBrightness ( bright ); + m_backlight_current = bright; + } } /** * Timer event used for automatic setting the backlight according to a light sensor * and to set the default brightness */ void OpieScreenSaver::timerEvent ( QTimerEvent * ) { - int s = ODevice::inst ( )-> readLightSensor ( ) * 256 / ODevice::inst ( )-> lightSensorResolution ( ); + int s = ODevice::inst ( )-> readLightSensor ( ) * 256 / ODevice::inst ( )-> lightSensorResolution ( ); - if ( s < m_sensordata [LS_SensorMin] ) - m_backlight_sensor = m_sensordata [LS_LightMax]; - else if ( s >= m_sensordata [LS_SensorMax] ) - m_backlight_sensor = m_sensordata [LS_LightMin]; - else { - int dx = m_sensordata [LS_SensorMax] - m_sensordata [LS_SensorMin]; - int dy = m_sensordata [LS_LightMax] - m_sensordata [LS_LightMin]; + if ( s < m_sensordata [LS_SensorMin] ) + m_backlight_sensor = m_sensordata [LS_LightMax]; + else if ( s >= m_sensordata [LS_SensorMax] ) + m_backlight_sensor = m_sensordata [LS_LightMin]; + else { + int dx = m_sensordata [LS_SensorMax] - m_sensordata [LS_SensorMin]; + int dy = m_sensordata [LS_LightMax] - m_sensordata [LS_LightMin]; - int stepno = ( s - m_sensordata [LS_SensorMin] ) * m_sensordata [LS_Steps] / dx; // dx is never 0 + int stepno = ( s - m_sensordata [LS_SensorMin] ) * m_sensordata [LS_Steps] / dx; // dx is never 0 - m_backlight_sensor = m_sensordata [LS_LightMax] - dy * stepno / ( m_sensordata [LS_Steps] - 1 ); - } + m_backlight_sensor = m_sensordata [LS_LightMax] - dy * stepno / ( m_sensordata [LS_Steps] - 1 ); + } - //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] ); + odebug << "f(" << s << ") = " << m_backlight_sensor << " [" << m_sensordata [LS_SensorMin] + << " - " << m_sensordata [LS_SensorMax] << " ] -> [" << m_sensordata [LS_LightMin] + << " - " << m_sensordata [LS_LightMax] << "] / " << m_sensordata [LS_Steps] << oendl; - if ( m_level <= 0 ) - setBacklightInternal ( -1 ); + if ( m_level <= 0 ) + setBacklightInternal ( -1 ); } /** * Like ODevice::setDisplayStatus(), but keep current state in m_lcd_status. */ void OpieScreenSaver::setDisplayState ( bool on ) { - if ( m_lcd_status != on ) { - ODevice::inst ( ) -> setDisplayStatus ( on ); - m_lcd_status = on; - } + if ( m_lcd_status != on ) { + ODevice::inst ( ) -> setDisplayStatus ( on ); + m_lcd_status = on; + } } /** * Set display to default ac/battery settings when power status changed. */ void OpieScreenSaver::powerStatusChanged ( PowerStatus ps ) { - bool newonac = ( ps. acStatus ( ) == PowerStatus::Online ); - - if ( newonac != m_on_ac ) { - m_on_ac = newonac; - setInterval ( -1 ); - setBacklight ( -1 ); - restore ( ); - } + bool newonac = ( ps. acStatus ( ) == PowerStatus::Online ); + + if ( newonac != m_on_ac ) { + m_on_ac = newonac; + setInterval ( -1 ); + setBacklight ( -1 ); + restore ( ); + } } 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 @@ -1,729 +1,729 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "server.h" #include "serverapp.h" #include "startmenu.h" #include "launcher.h" #include "transferserver.h" #include "qcopbridge.h" #include "irserver.h" #include "packageslave.h" #include "calibrate.h" #include "qrsync.h" #include "syncdialog.h" #include "shutdownimpl.h" #include "applauncher.h" #if 0 #include "suspendmonitor.h" #endif #include "documentlist.h" /* OPIE */ #include <opie2/odebug.h> #include <opie2/odevicebutton.h> #include <opie2/odevice.h> #include <qtopia/applnk.h> #include <qtopia/private/categories.h> #include <qtopia/mimetype.h> #include <qtopia/config.h> #include <qtopia/resource.h> #include <qtopia/version.h> #include <qtopia/storage.h> #include <qtopia/qcopenvelope_qws.h> #include <qtopia/global.h> using namespace Opie::Core; /* QT */ #include <qmainwindow.h> #include <qmessagebox.h> #include <qtimer.h> #include <qtextstream.h> #include <qwindowsystem_qws.h> #include <qgfx_qws.h> /* STD */ #include <unistd.h> #include <stdlib.h> extern QRect qt_maxWindowRect; static QWidget *calibrate(bool) { #ifdef Q_WS_QWS Calibrate *c = new Calibrate; c->show(); return c; #else return 0; #endif } #define FACTORY(T) \ static QWidget *new##T( bool maximized ) { \ - QWidget *w = new T( 0, 0, QWidget::WDestructiveClose | QWidget::WGroupLeader ); \ - if ( maximized ) { \ - if ( qApp->desktop()->width() <= 350 ) { \ - w->showMaximized(); \ - } else { \ - w->resize( QSize( 300, 300 ) ); \ - } \ - } \ - w->show(); \ - return w; \ + QWidget *w = new T( 0, 0, QWidget::WDestructiveClose | QWidget::WGroupLeader ); \ + if ( maximized ) { \ + if ( qApp->desktop()->width() <= 350 ) { \ + w->showMaximized(); \ + } else { \ + w->resize( QSize( 300, 300 ) ); \ + } \ + } \ + w->show(); \ + return w; \ } #ifdef SINGLE_APP #define APP(a,b,c,d) FACTORY(b) #include "apps.h" #undef APP #endif // SINGLE_APP static Global::Command builtins[] = { #ifdef SINGLE_APP #define APP(a,b,c,d) { a, new##b, c, d }, #include "apps.h" #undef APP #endif /* FIXME defines need to be defined*/ #if !defined(OPIE_NO_BUILTIN_CALIBRATE) - { "calibrate", calibrate, 1, 0 }, // No tr + { "calibrate", calibrate, 1, 0 }, // No tr #endif #if !defined(OPIE_NO_BUILTIN_SHUTDOWN) - { "shutdown", Global::shutdown, 1, 0 }, // No tr -// { "run", run, 1, 0 }, // No tr + { "shutdown", Global::shutdown, 1, 0 }, // No tr +// { "run", run, 1, 0 }, // No tr #endif - { 0, calibrate, 0, 0 }, + { 0, calibrate, 0, 0 }, }; //--------------------------------------------------------------------------- //=========================================================================== Server::Server() : QWidget( 0, 0, WStyle_Tool | WStyle_Customize ), qcopBridge( 0 ), transferServer( 0 ), packageHandler( 0 ), syncDialog( 0 ) { Global::setBuiltinCommands(builtins); tid_xfer = 0; /* ### FIXME ### */ /* tid_today = startTimer(3600*2*1000);*/ last_today_show = QDate::currentDate(); #if 0 tsmMonitor = new TempScreenSaverMode(); connect( tsmMonitor, SIGNAL(forceSuspend()), qApp, SIGNAL(power()) ); #endif serverGui = new Launcher; serverGui->createGUI(); docList = new DocumentList( serverGui ); appLauncher = new AppLauncher(this); connect(appLauncher, SIGNAL(launched(int,const QString&)), this, SLOT(applicationLaunched(int,const QString&)) ); connect(appLauncher, SIGNAL(terminated(int,const QString&)), this, SLOT(applicationTerminated(int,const QString&)) ); connect(appLauncher, SIGNAL(connected(const QString&)), this, SLOT(applicationConnected(const QString&)) ); storage = new StorageInfo( this ); connect( storage, SIGNAL(disksChanged()), this, SLOT(storageChanged()) ); // start services startTransferServer(); (void) new IrServer( this ); packageHandler = new PackageHandler( this ); connect(qApp, SIGNAL(activate(const Opie::Core::ODeviceButton*,bool)), this,SLOT(activate(const Opie::Core::ODeviceButton*,bool))); setGeometry( -10, -10, 9, 9 ); QCopChannel *channel = new QCopChannel("QPE/System", this); connect(channel, SIGNAL(received(const QCString&,const QByteArray&)), - this, SLOT(systemMsg(const QCString&,const QByteArray&)) ); + this, SLOT(systemMsg(const QCString&,const QByteArray&)) ); QCopChannel *tbChannel = new QCopChannel( "QPE/TaskBar", this ); connect( tbChannel, SIGNAL(received(const QCString&,const QByteArray&)), - this, SLOT(receiveTaskBar(const QCString&,const QByteArray&)) ); + this, SLOT(receiveTaskBar(const QCString&,const QByteArray&)) ); connect( qApp, SIGNAL(prepareForRestart()), this, SLOT(terminateServers()) ); connect( qApp, SIGNAL(timeChanged()), this, SLOT(pokeTimeMonitors()) ); preloadApps(); } void Server::show() { ServerApplication::login(TRUE); QWidget::show(); } Server::~Server() { serverGui->destroyGUI(); delete docList; delete qcopBridge; delete transferServer; delete serverGui; #if 0 delete tsmMonitor; #endif } static bool hasVisibleWindow(const QString& clientname, bool partial) { #ifdef QWS const QList<QWSWindow> &list = qwsServer->clientWindows(); QWSWindow* w; for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) { - if ( w->client()->identity() == clientname ) { - if ( partial && !w->isFullyObscured() ) - return TRUE; - if ( !partial && !w->isFullyObscured() && !w->isPartiallyObscured() ) { + if ( w->client()->identity() == clientname ) { + if ( partial && !w->isFullyObscured() ) + return TRUE; + if ( !partial && !w->isFullyObscured() && !w->isPartiallyObscured() ) { # if QT_VERSION < 0x030000 - QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, - QSize(qt_screen->width(),qt_screen->height()) ); + QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, + QSize(qt_screen->width(),qt_screen->height()) ); # else - QRect mwr = qt_maxWindowRect; + QRect mwr = qt_maxWindowRect; # endif - if ( mwr.contains(w->requested().boundingRect()) ) - return TRUE; - } - } + if ( mwr.contains(w->requested().boundingRect()) ) + return TRUE; + } + } } #endif return FALSE; } void Server::activate(const ODeviceButton* button, bool held) { Global::terminateBuiltin("calibrate"); // No tr OQCopMessage om; if ( held ) { - om = button->heldAction(); + om = button->heldAction(); } else { - om = button->pressedAction(); + om = button->pressedAction(); } if ( om.channel() != "ignore" ) om.send(); // A button with no action defined, will return a null ServiceRequest. Don't attempt // to send/do anything with this as it will crash /* ### FIXME */ #if 0 if ( !sr.isNull() ) { - QString app = sr.app(); - bool vis = hasVisibleWindow(app, app != "qpe"); - if ( sr.message() == "raise()" && vis ) { - sr.setMessage("nextView()"); - } else { - // "back door" - sr << (int)vis; - } - - sr.send(); + QString app = sr.app(); + bool vis = hasVisibleWindow(app, app != "qpe"); + if ( sr.message() == "raise()" && vis ) { + sr.setMessage("nextView()"); + } else { + // "back door" + sr << (int)vis; + } + + sr.send(); } #endif } #ifdef Q_WS_QWS typedef struct KeyOverride { ushort scan_code; QWSServer::KeyMap map; }; static const KeyOverride jp109keys[] = { { 0x03, { Qt::Key_2, '2' , 0x22 , 0xffff } }, { 0x07, { Qt::Key_6, '6' , '&' , 0xffff } }, { 0x08, { Qt::Key_7, '7' , '\'' , 0xffff } }, { 0x09, { Qt::Key_8, '8' , '(' , 0xffff } }, { 0x0a, { Qt::Key_9, '9' , ')' , 0xffff } }, { 0x0b, { Qt::Key_0, '0' , 0xffff , 0xffff } }, { 0x0c, { Qt::Key_Minus, '-' , '=' , 0xffff } }, { 0x0d, { Qt::Key_AsciiCircum,'^' , '~' , '^' - 64 } }, { 0x1a, { Qt::Key_At, '@' , '`' , 0xffff } }, { 0x1b, { Qt::Key_BraceLeft, '[' , '{' , '[' - 64 } }, { 0x27, { Qt::Key_Semicolon, ';' , '+' , 0xffff } }, { 0x28, { Qt::Key_Colon, ':' , '*' , 0xffff } }, { 0x29, { Qt::Key_Zenkaku_Hankaku, 0xffff , 0xffff , 0xffff } }, { 0x2b, { Qt::Key_BraceRight, ']' , '}' , ']'-64 } }, { 0x70, { Qt::Key_Hiragana_Katakana, 0xffff , 0xffff , 0xffff } }, { 0x73, { Qt::Key_Backslash, '\\' , '_' , 0xffff } }, { 0x79, { Qt::Key_Henkan, 0xffff , 0xffff , 0xffff } }, { 0x7b, { Qt::Key_Muhenkan, 0xffff , 0xffff , 0xffff } }, { 0x7d, { Qt::Key_yen, 0x00a5 , '|' , 0xffff } }, { 0x00, { 0, 0xffff , 0xffff , 0xffff } } }; bool Server::setKeyboardLayout( const QString &kb ) { //quick demo version that can be extended QIntDict<QWSServer::KeyMap> *om = 0; if ( kb == "us101" ) { // No tr - om = 0; + om = 0; } else if ( kb == "jp109" ) { - om = new QIntDict<QWSServer::KeyMap>(37); - const KeyOverride *k = jp109keys; - while ( k->scan_code ) { - om->insert( k->scan_code, &k->map ); - k++; - } + om = new QIntDict<QWSServer::KeyMap>(37); + const KeyOverride *k = jp109keys; + while ( k->scan_code ) { + om->insert( k->scan_code, &k->map ); + k++; + } } QWSServer::setOverrideKeys( om ); return TRUE; } #endif void Server::systemMsg(const QCString &msg, const QByteArray &data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "securityChanged()" ) { - if ( transferServer ) - transferServer->authorizeConnections(); - if ( qcopBridge ) - qcopBridge->authorizeConnections(); + if ( transferServer ) + transferServer->authorizeConnections(); + if ( qcopBridge ) + qcopBridge->authorizeConnections(); } /* ### FIXME support TempScreenSaverMode */ #if 0 else if ( msg == "setTempScreenSaverMode(int,int)" ) { - int mode, pid; - stream >> mode >> pid; - tsmMonitor->setTempMode(mode, pid); + int mode, pid; + stream >> mode >> pid; + tsmMonitor->setTempMode(mode, pid); } #endif else if ( msg == "linkChanged(QString)" ) { - QString link; - stream >> link; + QString link; + stream >> link; odebug << "desktop.cpp systemMsg -> linkchanged( " << link << " )" << oendl; - docList->linkChanged(link); + docList->linkChanged(link); } else if ( msg == "serviceChanged(QString)" ) { - MimeType::updateApplications(); + MimeType::updateApplications(); } else if ( msg == "mkdir(QString)" ) { - QString dir; - stream >> dir; - if ( !dir.isEmpty() ) - mkdir( dir ); + QString dir; + stream >> dir; + if ( !dir.isEmpty() ) + mkdir( dir ); } else if ( msg == "rdiffGenSig(QString,QString)" ) { - QString baseFile, sigFile; - stream >> baseFile >> sigFile; - QRsync::generateSignature( baseFile, sigFile ); + QString baseFile, sigFile; + stream >> baseFile >> sigFile; + QRsync::generateSignature( baseFile, sigFile ); } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) { - QString baseFile, sigFile, deltaFile; - stream >> baseFile >> sigFile >> deltaFile; - QRsync::generateDiff( baseFile, sigFile, deltaFile ); + QString baseFile, sigFile, deltaFile; + stream >> baseFile >> sigFile >> deltaFile; + QRsync::generateDiff( baseFile, sigFile, deltaFile ); } else if ( msg == "rdiffApplyPatch(QString,QString)" ) { - QString baseFile, deltaFile; - stream >> baseFile >> deltaFile; - if ( !QFile::exists( baseFile ) ) { - QFile f( baseFile ); - f.open( IO_WriteOnly ); - f.close(); - } - QRsync::applyDiff( baseFile, deltaFile ); + QString baseFile, deltaFile; + stream >> baseFile >> deltaFile; + if ( !QFile::exists( baseFile ) ) { + QFile f( baseFile ); + f.open( IO_WriteOnly ); + f.close(); + } + QRsync::applyDiff( baseFile, deltaFile ); #ifndef QT_NO_COP - QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" ); - e << baseFile; + QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" ); + e << baseFile; #endif } else if ( msg == "rdiffCleanup()" ) { - mkdir( "/tmp/rdiff" ); - QDir dir; - dir.setPath( "/tmp/rdiff" ); - QStringList entries = dir.entryList(); - for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it ) - dir.remove( *it ); + mkdir( "/tmp/rdiff" ); + QDir dir; + dir.setPath( "/tmp/rdiff" ); + QStringList entries = dir.entryList(); + for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it ) + dir.remove( *it ); } else if ( msg == "sendHandshakeInfo()" ) { - QString home = getenv( "HOME" ); + QString home = getenv( "HOME" ); #ifndef QT_NO_COP - QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" ); - e << home; - int locked = (int) ServerApplication::screenLocked(); - e << locked; + QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" ); + e << home; + int locked = (int) ServerApplication::screenLocked(); + e << locked; #endif } /* * QtopiaDesktop relies on the major number * to start with 1. We're at 0.9 * so wee need to fake at least 1.4 to be able * to sync with QtopiaDesktop1.6 */ else if ( msg == "sendVersionInfo()" ) { - QCopEnvelope e( "QPE/Desktop", "versionInfo(QString,QString)" ); + QCopEnvelope e( "QPE/Desktop", "versionInfo(QString,QString)" ); /* ### FIXME Architecture ### */ - e << QString::fromLatin1("1.7") << "Uncustomized Device"; + e << QString::fromLatin1("1.7") << "Uncustomized Device"; } else if ( msg == "sendCardInfo()" ) { #ifndef QT_NO_COP - QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" ); + QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" ); #endif - storage->update(); - const QList<FileSystem> &fs = storage->fileSystems(); - QListIterator<FileSystem> it ( fs ); - QString s; - QString homeDir = getenv("HOME"); - QString homeFs, homeFsPath; - for ( ; it.current(); ++it ) { - int k4 = (*it)->blockSize()/256; - if ( (*it)->isRemovable() ) { - s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr - + QString::number( (*it)->availBlocks() * k4/4 ) - + "K " + (*it)->options() + ";"; - } else if ( homeDir.contains( (*it)->path() ) && - (*it)->path().length() > homeFsPath.length() ) { - homeFsPath = (*it)->path(); - homeFs = - (*it)->name() + "=" + homeDir + "/Documents " // No tr - + QString::number( (*it)->availBlocks() * k4/4 ) - + "K " + (*it)->options() + ";"; - } - } - if ( !homeFs.isEmpty() ) - s += homeFs; + storage->update(); + const QList<FileSystem> &fs = storage->fileSystems(); + QListIterator<FileSystem> it ( fs ); + QString s; + QString homeDir = getenv("HOME"); + QString homeFs, homeFsPath; + for ( ; it.current(); ++it ) { + int k4 = (*it)->blockSize()/256; + if ( (*it)->isRemovable() ) { + s += (*it)->name() + "=" + (*it)->path() + "/Documents " // No tr + + QString::number( (*it)->availBlocks() * k4/4 ) + + "K " + (*it)->options() + ";"; + } else if ( homeDir.contains( (*it)->path() ) && + (*it)->path().length() > homeFsPath.length() ) { + homeFsPath = (*it)->path(); + homeFs = + (*it)->name() + "=" + homeDir + "/Documents " // No tr + + QString::number( (*it)->availBlocks() * k4/4 ) + + "K " + (*it)->options() + ";"; + } + } + if ( !homeFs.isEmpty() ) + s += homeFs; #ifndef QT_NO_COP - e << s; + e << s; #endif } else if ( msg == "sendSyncDate(QString)" ) { - QString app; - stream >> app; - Config cfg( "qpe" ); - cfg.setGroup("SyncDate"); + QString app; + stream >> app; + Config cfg( "qpe" ); + cfg.setGroup("SyncDate"); #ifndef QT_NO_COP - QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" ); - e << app << cfg.readEntry( app ); + QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" ); + e << app << cfg.readEntry( app ); #endif - //qDebug("QPE/System sendSyncDate for %s: response %s", app.latin1(), - //cfg.readEntry( app ).latin1() ); + //odebug << "QPE/System sendSyncDate for " << app.latin1() << ": response " + // << cfg.readEntry( app ).latin1() << oendl; } else if ( msg == "setSyncDate(QString,QString)" ) { - QString app, date; - stream >> app >> date; - Config cfg( "qpe" ); - cfg.setGroup("SyncDate"); - cfg.writeEntry( app, date ); + QString app, date; + stream >> app >> date; + Config cfg( "qpe" ); + cfg.setGroup("SyncDate"); + cfg.writeEntry( app, date ); //odebug << "setSyncDate(QString,QString) " << app << " " << date << "" << oendl; } else if ( msg == "startSync(QString)" ) { - QString what; - stream >> what; - delete syncDialog; - syncDialog = new SyncDialog( this, what ); - syncDialog->show(); - connect( syncDialog, SIGNAL(cancel()), SLOT(cancelSync()) ); + QString what; + stream >> what; + delete syncDialog; + syncDialog = new SyncDialog( this, what ); + syncDialog->show(); + connect( syncDialog, SIGNAL(cancel()), SLOT(cancelSync()) ); } else if ( msg == "stopSync()") { - delete syncDialog; - syncDialog = 0; + delete syncDialog; + syncDialog = 0; } else if (msg == "restoreDone(QString)") { - docList->restoreDone(); + docList->restoreDone(); } else if ( msg == "getAllDocLinks()" ) { - docList->sendAllDocLinks(); + docList->sendAllDocLinks(); } #ifdef Q_WS_QWS else if ( msg == "setMouseProto(QString)" ) { - QString mice; - stream >> mice; - setenv("QWS_MOUSE_PROTO",mice.latin1(),1); - qwsServer->openMouse(); + QString mice; + stream >> mice; + setenv("QWS_MOUSE_PROTO",mice.latin1(),1); + qwsServer->openMouse(); } else if ( msg == "setKeyboard(QString)" ) { - QString kb; - stream >> kb; - setenv("QWS_KEYBOARD",kb.latin1(),1); - qwsServer->openKeyboard(); + QString kb; + stream >> kb; + setenv("QWS_KEYBOARD",kb.latin1(),1); + qwsServer->openKeyboard(); } else if ( msg == "setKeyboardAutoRepeat(int,int)" ) { - int delay, period; - stream >> delay >> period; - qwsSetKeyboardAutoRepeat( delay, period ); - Config cfg( "qpe" ); - cfg.setGroup("Keyboard"); - cfg.writeEntry( "RepeatDelay", delay ); - cfg.writeEntry( "RepeatPeriod", period ); + int delay, period; + stream >> delay >> period; + qwsSetKeyboardAutoRepeat( delay, period ); + Config cfg( "qpe" ); + cfg.setGroup("Keyboard"); + cfg.writeEntry( "RepeatDelay", delay ); + cfg.writeEntry( "RepeatPeriod", period ); } else if ( msg == "setKeyboardLayout(QString)" ) { - QString kb; - stream >> kb; - setKeyboardLayout( kb ); - Config cfg( "qpe" ); - cfg.setGroup("Keyboard"); - cfg.writeEntry( "Layout", kb ); + QString kb; + stream >> kb; + setKeyboardLayout( kb ); + Config cfg( "qpe" ); + cfg.setGroup("Keyboard"); + cfg.writeEntry( "Layout", kb ); } else if ( msg == "autoStart(QString)" ) { QString appName; stream >> appName; Config cfg( "autostart" ); cfg.setGroup( "AutoStart" ); if ( appName.compare("clear") == 0){ cfg.writeEntry("Apps", ""); } } else if ( msg == "autoStart(QString,QString)" ) { QString modifier, appName; stream >> modifier >> appName; Config cfg( "autostart" ); cfg.setGroup( "AutoStart" ); if ( modifier.compare("add") == 0 ){ // only add if appname is entered if (!appName.isEmpty()) { cfg.writeEntry("Apps", appName); } } else if (modifier.compare("remove") == 0 ) { // need to change for multiple entries // actually remove is right now simular to clear, but in future there // should be multiple apps in autostart possible. QString checkName; checkName = cfg.readEntry("Apps", ""); if (checkName == appName) { cfg.writeEntry("Apps", ""); } } // case the autostart feature should be delayed } else if ( msg == "autoStart(QString,QString,QString)") { QString modifier, appName, delay; stream >> modifier >> appName >> delay; Config cfg( "autostart" ); cfg.setGroup( "AutoStart" ); if ( modifier.compare("add") == 0 ){ // only add it appname is entered if (!appName.isEmpty()) { cfg.writeEntry("Apps", appName); cfg.writeEntry("Delay", delay); } } else { } } #endif } void Server::receiveTaskBar(const QCString &msg, const QByteArray &data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "reloadApps()" ) { - docList->reloadAppLnks(); + docList->reloadAppLnks(); } else if ( msg == "soundAlarm()" ) { - ServerApplication::soundAlarm(); + ServerApplication::soundAlarm(); } else if ( msg == "setLed(int,bool)" ) { - int led, status; - stream >> led >> status; + int led, status; + stream >> led >> status; QValueList <OLed> ll = ODevice::inst ( )-> ledList ( ); - if ( ll. count ( )) { + if ( ll. count ( )) { OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0]; bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow ); ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off ); } } } void Server::cancelSync() { #ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "cancelSync()" ); #endif delete syncDialog; syncDialog = 0; } bool Server::mkdir(const QString &localPath) { QDir fullDir(localPath); if (fullDir.exists()) - return true; + return true; // at this point the directory doesn't exist // go through the directory tree and start creating the direcotories // that don't exist; if we can't create the directories, return false QString dirSeps = "/"; int dirIndex = localPath.find(dirSeps); QString checkedPath; // didn't find any seps; weird, use the cur dir instead if (dirIndex == -1) { //odebug << "No seperators found in path " << localPath << "" << oendl; - checkedPath = QDir::currentDirPath(); + checkedPath = QDir::currentDirPath(); } while (checkedPath != localPath) { - // no more seperators found, use the local path - if (dirIndex == -1) - checkedPath = localPath; - else { - // the next directory to check - checkedPath = localPath.left(dirIndex) + "/"; - // advance the iterator; the next dir seperator - dirIndex = localPath.find(dirSeps, dirIndex+1); - } - - QDir checkDir(checkedPath); - if (!checkDir.exists()) { + // no more seperators found, use the local path + if (dirIndex == -1) + checkedPath = localPath; + else { + // the next directory to check + checkedPath = localPath.left(dirIndex) + "/"; + // advance the iterator; the next dir seperator + dirIndex = localPath.find(dirSeps, dirIndex+1); + } + + QDir checkDir(checkedPath); + if (!checkDir.exists()) { //odebug << "mkdir making dir " << checkedPath << "" << oendl; - if (!checkDir.mkdir(checkedPath)) { + if (!checkDir.mkdir(checkedPath)) { odebug << "Unable to make directory " << checkedPath << "" << oendl; - return FALSE; - } - } + return FALSE; + } + } } return TRUE; } void Server::styleChange( QStyle &s ) { QWidget::styleChange( s ); } void Server::startTransferServer() { if ( !qcopBridge ) { - // start qcop bridge server - qcopBridge = new QCopBridge( 4243 ); - if ( qcopBridge->ok() ) { - // ... OK - connect( qcopBridge, SIGNAL(connectionClosed(const QHostAddress&)), - this, SLOT(syncConnectionClosed(const QHostAddress&)) ); - } else { - delete qcopBridge; - qcopBridge = 0; - } + // start qcop bridge server + qcopBridge = new QCopBridge( 4243 ); + if ( qcopBridge->ok() ) { + // ... OK + connect( qcopBridge, SIGNAL(connectionClosed(const QHostAddress&)), + this, SLOT(syncConnectionClosed(const QHostAddress&)) ); + } else { + delete qcopBridge; + qcopBridge = 0; + } } if ( !transferServer ) { - // start transfer server - transferServer = new TransferServer( 4242 ); - if ( transferServer->ok() ) { - // ... OK - } else { - delete transferServer; - transferServer = 0; - } + // start transfer server + transferServer = new TransferServer( 4242 ); + if ( transferServer->ok() ) { + // ... OK + } else { + delete transferServer; + transferServer = 0; + } } if ( !transferServer || !qcopBridge ) - tid_xfer = startTimer( 2000 ); + tid_xfer = startTimer( 2000 ); } void Server::timerEvent( QTimerEvent *e ) { if ( e->timerId() == tid_xfer ) { - killTimer( tid_xfer ); - tid_xfer = 0; - startTransferServer(); + killTimer( tid_xfer ); + tid_xfer = 0; + startTransferServer(); } /* ### FIXME today startin */ #if 0 else if ( e->timerId() == tid_today ) { - QDate today = QDate::currentDate(); - if ( today != last_today_show ) { - last_today_show = today; - Config cfg("today"); - cfg.setGroup("Start"); + QDate today = QDate::currentDate(); + if ( today != last_today_show ) { + last_today_show = today; + Config cfg("today"); + cfg.setGroup("Start"); #ifndef QPE_DEFAULT_TODAY_MODE #define QPE_DEFAULT_TODAY_MODE "Never" #endif - if ( cfg.readEntry("Mode",QPE_DEFAULT_TODAY_MODE) == "Daily" ) { - QCopEnvelope env(Service::channel("today"),"raise()"); - } - } + if ( cfg.readEntry("Mode",QPE_DEFAULT_TODAY_MODE) == "Daily" ) { + QCopEnvelope env(Service::channel("today"),"raise()"); + } + } } #endif } void Server::terminateServers() { delete transferServer; delete qcopBridge; transferServer = 0; qcopBridge = 0; } void Server::syncConnectionClosed( const QHostAddress & ) { odebug << "Lost sync connection" << oendl; delete syncDialog; syncDialog = 0; } void Server::pokeTimeMonitors() { #if 0 // inform all TimeMonitors QStrList tms = Service::channels("TimeMonitor"); for (const char* ch = tms.first(); ch; ch=tms.next()) { - QString t = getenv("TZ"); - QCopEnvelope e(ch, "timeChange(QString)"); - e << t; + QString t = getenv("TZ"); + QCopEnvelope e(ch, "timeChange(QString)"); + e << t; } #endif } void Server::applicationLaunched(int, const QString &app) { serverGui->applicationStateChanged( app, ServerInterface::Launching ); } void Server::applicationTerminated(int pid, const QString &app) { serverGui->applicationStateChanged( app, ServerInterface::Terminated ); #if 0 tsmMonitor->applicationTerminated( pid ); #endif } void Server::applicationConnected(const QString &app) { serverGui->applicationStateChanged( app, ServerInterface::Running ); } void Server::storageChanged() { system( "opie-update-symlinks" ); serverGui->storageChanged( storage->fileSystems() ); docList->storageChanged(); } void Server::preloadApps() { Config cfg("Launcher"); cfg.setGroup("Preload"); QStringList apps = cfg.readListEntry("Apps",','); for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) { #ifndef QT_NO_COP - QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()"); + QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()"); #endif } } 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 @@ -1,1431 +1,1430 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "transferserver.h" /* OPIE */ #include <opie2/odebug.h> #include <opie2/oglobal.h> #include <qtopia/qprocess.h> #include <qtopia/process.h> #include <qtopia/private/contact.h> #include <qtopia/version.h> #ifdef Q_WS_QWS #include <qtopia/qcopenvelope_qws.h> #endif using namespace Opie::Core; /* QT */ #include <qtextstream.h> #include <qmessagebox.h> /* STD */ #include <pwd.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <time.h> #ifndef Q_OS_MACX #include <shadow.h> #include <crypt.h> #endif /* Q_OS_MACX */ const int block_size = 51200; TransferServer::TransferServer( Q_UINT16 port, QObject *parent, const char* name) : QServerSocket( port, 1, parent, name ) { connections.setAutoDelete( TRUE ); if ( !ok() ) owarn << "Failed to bind to port " << port << "" << oendl; } void TransferServer::authorizeConnections() { QListIterator<ServerPI> it(connections); while ( it.current() ) { - if ( !it.current()->verifyAuthorised() ) { - disconnect( it.current(), SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); - connections.removeRef( it.current() ); - } else - ++it; + if ( !it.current()->verifyAuthorised() ) { + disconnect( it.current(), SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); + connections.removeRef( it.current() ); + } else + ++it; } } void TransferServer::closed(ServerPI *item) { connections.removeRef(item); } TransferServer::~TransferServer() { } void TransferServer::newConnection( int socket ) { ServerPI *ptr = new ServerPI( socket, this ); connect( ptr, SIGNAL(connectionClosed(ServerPI*)), this, SLOT( closed(ServerPI*)) ); connections.append( ptr ); } QString SyncAuthentication::serverId() { Config cfg("Security"); cfg.setGroup("Sync"); QString r = cfg.readEntry("serverid"); if ( r.isEmpty() ) { r = OGlobal::generateUuid(); cfg.writeEntry("serverid", r ); } return r; } QString SyncAuthentication::ownerName() { QString vfilename = Global::applicationFileName("addressbook", "businesscard.vcf"); if (QFile::exists(vfilename)) { - Contact c; - c = Contact::readVCard( vfilename )[0]; - return c.fullName(); + Contact c; + c = Contact::readVCard( vfilename )[0]; + return c.fullName(); } return QString::null; } QString SyncAuthentication::loginName() { struct passwd *pw = 0L; #ifndef Q_OS_WIN32 pw = getpwuid( geteuid() ); return QString::fromLocal8Bit( pw->pw_name ); #else //### revise return QString(); #endif } int SyncAuthentication::isAuthorized(QHostAddress peeraddress) { Config cfg("Security"); - cfg.setGroup("Sync"); - // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); - uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100); - - // QHostAddress allowed; - // allowed.setAddress(allowedstr); - // uint auth_peer = allowed.ip4Addr(); - uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24); - uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined - ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits)); - - return (peeraddress.ip4Addr() & mask) == auth_peer; + cfg.setGroup("Sync"); + // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); + uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100); + + // QHostAddress allowed; + // allowed.setAddress(allowedstr); + // uint auth_peer = allowed.ip4Addr(); + uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24); + uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined + ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits)); + + return (peeraddress.ip4Addr() & mask) == auth_peer; } bool SyncAuthentication::checkUser( const QString& user ) { if ( user.isEmpty() ) return FALSE; QString euser = loginName(); return user == euser; } bool SyncAuthentication::checkPassword( const QString& password ) { #ifdef ALLOW_UNIX_USER_FTP // First, check system password... struct passwd *pw = 0; struct spwd *spw = 0; pw = getpwuid( geteuid() ); spw = getspnam( pw->pw_name ); QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); if ( cpwd == "x" && spw ) - cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); + cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); // Note: some systems use more than crypt for passwords. QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); if ( cpwd == cpassword ) - return TRUE; + return TRUE; #endif static int lastdenial=0; static int denials=0; int now = time(0); Config cfg("Security"); cfg.setGroup("SyncMode"); int mode = cfg.readNumEntry("Mode", 0x02 ); //No pass word needed if the user really needs it if (mode & 0x04) { QMessageBox unauth( tr("Sync Connection"), tr("<qt><p>An unauthorized system is requesting access to this device." "<p>You chose IntelliSync so you may I allow or deny this connection.</qt>" ), QMessageBox::Warning, QMessageBox::Ok, QMessageBox::Cancel|QMessageBox::Default, QMessageBox::NoButton, 0, QString::null, TRUE, WStyle_StaysOnTop); unauth.setButtonText(QMessageBox::Ok, tr("Allow" ) ); unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); switch( unauth.exec() ) { case QMessageBox::Ok: return TRUE; break; case QMessageBox::Cancel: default: denials++; lastdenial=now; return FALSE; } } // Detect old Qtopia Desktop (no password) and fail if ( password.isEmpty() ) { - if ( denials < 3 || now > lastdenial+600 ) { - QMessageBox unauth( - tr("Sync Connection"), - tr("<p>An unauthorized system is requesting access to this device." - "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " - "please upgrade or change the security setting to use IntelliSync." ), - QMessageBox::Warning, - QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton, - 0, QString::null, TRUE, WStyle_StaysOnTop); - unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); - unauth.exec(); + if ( denials < 3 || now > lastdenial+600 ) { + QMessageBox unauth( + tr("Sync Connection"), + tr("<p>An unauthorized system is requesting access to this device." + "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " + "please upgrade or change the security setting to use IntelliSync." ), + QMessageBox::Warning, + QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton, + 0, QString::null, TRUE, WStyle_StaysOnTop); + unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); + unauth.exec(); - denials++; - lastdenial=now; - } - return FALSE; + denials++; + lastdenial=now; + } + return FALSE; } // Second, check sync password... static int lock=0; if ( lock ) return FALSE; ++lock; /* * we need to support old Sync software and QtopiaDesktop */ if ( password.left(6) == "Qtopia" || password.left(6) == "rootme" ) { - Config cfg( "Security" ); - cfg.setGroup("Sync"); - QStringList pwds = cfg.readListEntry("Passwords",' '); - for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) { + Config cfg( "Security" ); + cfg.setGroup("Sync"); + QStringList pwds = cfg.readListEntry("Passwords",' '); + for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) { #ifndef Q_OS_WIN32 - QString cpassword = QString::fromLocal8Bit( - crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); + QString cpassword = QString::fromLocal8Bit( + crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); #else - // ### revise - QString cpassword(""); + // ### revise + QString cpassword(""); #endif - if ( *it == cpassword ) { - lock--; - return TRUE; - } - } - - // Unrecognized system. Be careful... - QMessageBox unrecbox( - tr("Sync Connection"), - tr( "<p>An unrecognized system is requesting access to this device." - "<p>If you have just initiated a Sync for the first time, this is normal."), - QMessageBox::Warning, - QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton, - 0, QString::null, TRUE, WStyle_StaysOnTop); - unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny")); - unrecbox.setButtonText(QMessageBox::Yes, tr("Allow")); - - if ( (denials > 2 && now < lastdenial+600) - || unrecbox.exec() != QMessageBox::Yes) - { - denials++; - lastdenial=now; - lock--; - return FALSE; - } else { - const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."; - char salt[2]; - salt[0]= salty[rand() % (sizeof(salty)-1)]; - salt[1]= salty[rand() % (sizeof(salty)-1)]; + if ( *it == cpassword ) { + lock--; + return TRUE; + } + } + + // Unrecognized system. Be careful... + QMessageBox unrecbox( + tr("Sync Connection"), + tr( "<p>An unrecognized system is requesting access to this device." + "<p>If you have just initiated a Sync for the first time, this is normal."), + QMessageBox::Warning, + QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton, + 0, QString::null, TRUE, WStyle_StaysOnTop); + unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny")); + unrecbox.setButtonText(QMessageBox::Yes, tr("Allow")); + + if ( (denials > 2 && now < lastdenial+600) + || unrecbox.exec() != QMessageBox::Yes) + { + denials++; + lastdenial=now; + lock--; + return FALSE; + } else { + const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."; + char salt[2]; + salt[0]= salty[rand() % (sizeof(salty)-1)]; + salt[1]= salty[rand() % (sizeof(salty)-1)]; #ifndef Q_OS_WIN32 - QString cpassword = QString::fromLocal8Bit( - crypt( password.mid(8).local8Bit(), salt ) ); + QString cpassword = QString::fromLocal8Bit( + crypt( password.mid(8).local8Bit(), salt ) ); #else - //### revise - QString cpassword(""); + //### revise + QString cpassword(""); #endif - denials=0; - pwds.prepend(cpassword); - cfg.writeEntry("Passwords",pwds,' '); - lock--; - return TRUE; - } + denials=0; + pwds.prepend(cpassword); + cfg.writeEntry("Passwords",pwds,' '); + lock--; + return TRUE; + } } lock--; return FALSE; } ServerPI::ServerPI( int socket, QObject *parent, const char* name ) : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ), storFileSize(-1) { state = Connected; setSocket( socket ); peerport = peerPort(); peeraddress = peerAddress(); #ifndef INSECURE if ( !SyncAuthentication::isAuthorized(peeraddress) ) { - state = Forbidden; - startTimer( 0 ); + state = Forbidden; + startTimer( 0 ); } else #endif { - connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); - connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); + connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); + connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); - passiv = FALSE; - for( int i = 0; i < 4; i++ ) - wait[i] = FALSE; + passiv = FALSE; + for( int i = 0; i < 4; i++ ) + wait[i] = FALSE; - send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr - state = Wait_USER; + send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr + state = Wait_USER; - dtp = new ServerDTP( this ); - connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); - connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); - connect( dtp, SIGNAL( error(int) ), SLOT( dtpError(int) ) ); + dtp = new ServerDTP( this ); + connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); + connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); + connect( dtp, SIGNAL( error(int) ), SLOT( dtpError(int) ) ); - directory = QDir::currentDirPath(); + directory = QDir::currentDirPath(); - static int p = 1024; + static int p = 1024; - while ( !serversocket || !serversocket->ok() ) { - delete serversocket; - serversocket = new ServerSocket( ++p, this ); - } - connect( serversocket, SIGNAL( newIncomming(int) ), - SLOT( newConnection(int) ) ); + while ( !serversocket || !serversocket->ok() ) { + delete serversocket; + serversocket = new ServerSocket( ++p, this ); + } + connect( serversocket, SIGNAL( newIncomming(int) ), + SLOT( newConnection(int) ) ); } } ServerPI::~ServerPI() { close(); if ( dtp ) dtp->close(); delete dtp; delete serversocket; } bool ServerPI::verifyAuthorised() { if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { - state = Forbidden; - return FALSE; + state = Forbidden; + return FALSE; } return TRUE; } void ServerPI::connectionClosed() { // odebug << "Debug: Connection closed" << oendl; emit connectionClosed(this); } void ServerPI::send( const QString& msg ) { QTextStream os( this ); os << msg << endl; //odebug << "Reply: " << msg << "" << oendl; } void ServerPI::read() { while ( canReadLine() ) - process( readLine().stripWhiteSpace() ); + process( readLine().stripWhiteSpace() ); } bool ServerPI::checkReadFile( const QString& file ) { QString filename; if ( file[0] != "/" ) - filename = directory.path() + "/" + file; + filename = directory.path() + "/" + file; else - filename = file; + filename = file; QFileInfo fi( filename ); return ( fi.exists() && fi.isReadable() ); } bool ServerPI::checkWriteFile( const QString& file ) { QString filename; if ( file[0] != "/" ) - filename = directory.path() + "/" + file; + filename = directory.path() + "/" + file; else - filename = file; + filename = file; QFileInfo fi( filename ); if ( fi.exists() ) - if ( !QFile( filename ).remove() ) - return FALSE; + if ( !QFile( filename ).remove() ) + return FALSE; return TRUE; } void ServerPI::process( const QString& message ) { //odebug << "Command: " << message << "" << oendl; // split message using "," as separator QStringList msg = QStringList::split( " ", message ); if ( msg.isEmpty() ) return; // command token QString cmd = msg[0].upper(); // argument token QString arg; if ( msg.count() >= 2 ) - arg = msg[1]; + arg = msg[1]; // full argument string QString args; if ( msg.count() >= 2 ) { QStringList copy( msg ); // FIXME: for Qt3 // copy.pop_front() copy.remove( copy.begin() ); args = copy.join( " " ); } //odebug << "args: " << args << "" << oendl; // we always respond to QUIT, regardless of state if ( cmd == "QUIT" ) { - send( "211 Good bye!" ); // No tr - close(); - return; + send( "211 Good bye!" ); // No tr + close(); + return; } // connected to client if ( Connected == state ) - return; + return; // waiting for user name if ( Wait_USER == state ) { - if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { - send( "530 Please login with USER and PASS" ); // No tr - return; - } - send( "331 User name ok, need password" ); // No tr - state = Wait_PASS; - return; + if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { + send( "530 Please login with USER and PASS" ); // No tr + return; + } + send( "331 User name ok, need password" ); // No tr + state = Wait_PASS; + return; } // waiting for password if ( Wait_PASS == state ) { - if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { - send( "530 Please login with USER and PASS" ); // No tr - return; - } - send( "230 User logged in, proceed" ); // No tr - state = Ready; - return; + if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { + send( "530 Please login with USER and PASS" ); // No tr + return; + } + send( "230 User logged in, proceed" ); // No tr + state = Ready; + return; } // ACCESS CONTROL COMMANDS // Only an ALLO sent immediately before STOR is valid. if ( cmd != "STOR" ) - storFileSize = -1; + storFileSize = -1; // account (ACCT) if ( cmd == "ACCT" ) { - // even wu-ftp does not support it - send( "502 Command not implemented" ); // No tr + // even wu-ftp does not support it + send( "502 Command not implemented" ); // No tr } // change working directory (CWD) else if ( cmd == "CWD" ) { - if ( !args.isEmpty() ) { - if ( directory.cd( args, TRUE ) ) - send( "250 Requested file action okay, completed" ); // No tr - else - send( "550 Requested action not taken" ); // No tr - } - else - send( "500 Syntax error, command unrecognized" ); // No tr + if ( !args.isEmpty() ) { + if ( directory.cd( args, TRUE ) ) + send( "250 Requested file action okay, completed" ); // No tr + else + send( "550 Requested action not taken" ); // No tr + } + else + send( "500 Syntax error, command unrecognized" ); // No tr } // change to parent directory (CDUP) else if ( cmd == "CDUP" ) { - if ( directory.cdUp() ) - send( "250 Requested file action okay, completed" ); // No tr - else - send( "550 Requested action not taken" ); // No tr + if ( directory.cdUp() ) + send( "250 Requested file action okay, completed" ); // No tr + else + send( "550 Requested action not taken" ); // No tr } // structure mount (SMNT) else if ( cmd == "SMNT" ) { - // even wu-ftp does not support it - send( "502 Command not implemented" ); // No tr + // even wu-ftp does not support it + send( "502 Command not implemented" ); // No tr } // reinitialize (REIN) else if ( cmd == "REIN" ) { - // even wu-ftp does not support it - send( "502 Command not implemented" ); // No tr + // even wu-ftp does not support it + send( "502 Command not implemented" ); // No tr } // TRANSFER PARAMETER COMMANDS // data port (PORT) else if ( cmd == "PORT" ) { - if ( parsePort( arg ) ) - send( "200 Command okay" ); // No tr - else - send( "500 Syntax error, command unrecognized" ); // No tr + if ( parsePort( arg ) ) + send( "200 Command okay" ); // No tr + else + send( "500 Syntax error, command unrecognized" ); // No tr } // passive (PASV) else if ( cmd == "PASV" ) { - passiv = TRUE; - send( "227 Entering Passive Mode (" // No tr - + address().toString().replace( QRegExp( "\\." ), "," ) + "," - + QString::number( ( serversocket->port() ) >> 8 ) + "," - + QString::number( ( serversocket->port() ) & 0xFF ) +")" ); + passiv = TRUE; + send( "227 Entering Passive Mode (" // No tr + + address().toString().replace( QRegExp( "\\." ), "," ) + "," + + QString::number( ( serversocket->port() ) >> 8 ) + "," + + QString::number( ( serversocket->port() ) & 0xFF ) +")" ); } // representation type (TYPE) else if ( cmd == "TYPE" ) { - if ( arg.upper() == "A" || arg.upper() == "I" ) - send( "200 Command okay" ); // No tr - else - send( "504 Command not implemented for that parameter" ); // No tr + if ( arg.upper() == "A" || arg.upper() == "I" ) + send( "200 Command okay" ); // No tr + else + send( "504 Command not implemented for that parameter" ); // No tr } // file structure (STRU) else if ( cmd == "STRU" ) { - if ( arg.upper() == "F" ) - send( "200 Command okay" ); // No tr - else - send( "504 Command not implemented for that parameter" ); // No tr + if ( arg.upper() == "F" ) + send( "200 Command okay" ); // No tr + else + send( "504 Command not implemented for that parameter" ); // No tr } // transfer mode (MODE) else if ( cmd == "MODE" ) { - if ( arg.upper() == "S" ) - send( "200 Command okay" ); // No tr - else - send( "504 Command not implemented for that parameter" ); // No tr + if ( arg.upper() == "S" ) + send( "200 Command okay" ); // No tr + else + send( "504 Command not implemented for that parameter" ); // No tr } // FTP SERVICE COMMANDS // retrieve (RETR) else if ( cmd == "RETR" ) - if ( !args.isEmpty() && checkReadFile( absFilePath( args ) ) - || backupRestoreGzip( absFilePath( args ) ) ) { - send( "150 File status okay" ); // No tr - sendFile( absFilePath( args ) ); - } - else { + if ( !args.isEmpty() && checkReadFile( absFilePath( args ) ) + || backupRestoreGzip( absFilePath( args ) ) ) { + send( "150 File status okay" ); // No tr + sendFile( absFilePath( args ) ); + } + else { odebug << "550 Requested action not taken" << oendl; - send( "550 Requested action not taken" ); // No tr - } + send( "550 Requested action not taken" ); // No tr + } // store (STOR) else if ( cmd == "STOR" ) - if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) { - send( "150 File status okay" ); // No tr - retrieveFile( absFilePath( args ) ); - } - else - send( "550 Requested action not taken" ); // No tr + if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) { + send( "150 File status okay" ); // No tr + retrieveFile( absFilePath( args ) ); + } + else + send( "550 Requested action not taken" ); // No tr // store unique (STOU) else if ( cmd == "STOU" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // append (APPE) else if ( cmd == "APPE" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // allocate (ALLO) else if ( cmd == "ALLO" ) { - storFileSize = args.toInt(); - send( "200 Command okay" ); // No tr + storFileSize = args.toInt(); + send( "200 Command okay" ); // No tr } // restart (REST) else if ( cmd == "REST" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // rename from (RNFR) else if ( cmd == "RNFR" ) { - renameFrom = QString::null; - if ( args.isEmpty() ) - send( "500 Syntax error, command unrecognized" ); // No tr - else { - QFile file( absFilePath( args ) ); - if ( file.exists() ) { - send( "350 File exists, ready for destination name" ); // No tr - renameFrom = absFilePath( args ); - } - else - send( "550 Requested action not taken" ); // No tr - } + renameFrom = QString::null; + if ( args.isEmpty() ) + send( "500 Syntax error, command unrecognized" ); // No tr + else { + QFile file( absFilePath( args ) ); + if ( file.exists() ) { + send( "350 File exists, ready for destination name" ); // No tr + renameFrom = absFilePath( args ); + } + else + send( "550 Requested action not taken" ); // No tr + } } // rename to (RNTO) else if ( cmd == "RNTO" ) { - if ( lastCommand != "RNFR" ) - send( "503 Bad sequence of commands" ); // No tr - else if ( args.isEmpty() ) - send( "500 Syntax error, command unrecognized" ); // No tr - else { - QDir dir( absFilePath( args ) ); - if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) - send( "250 Requested file action okay, completed." ); // No tr - else - send( "550 Requested action not taken" ); // No tr - } + if ( lastCommand != "RNFR" ) + send( "503 Bad sequence of commands" ); // No tr + else if ( args.isEmpty() ) + send( "500 Syntax error, command unrecognized" ); // No tr + else { + QDir dir( absFilePath( args ) ); + if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) + send( "250 Requested file action okay, completed." ); // No tr + else + send( "550 Requested action not taken" ); // No tr + } } // abort (ABOR) else if ( cmd.contains( "ABOR" ) ) { - dtp->close(); - if ( dtp->dtpMode() != ServerDTP::Idle ) - send( "426 Connection closed; transfer aborted" ); // No tr - else - send( "226 Closing data connection" ); // No tr + dtp->close(); + if ( dtp->dtpMode() != ServerDTP::Idle ) + send( "426 Connection closed; transfer aborted" ); // No tr + else + send( "226 Closing data connection" ); // No tr } // delete (DELE) else if ( cmd == "DELE" ) { - if ( args.isEmpty() ) - send( "500 Syntax error, command unrecognized" ); // No tr - else { - QFile file( absFilePath( args ) ) ; - if ( file.remove() ) { - send( "250 Requested file action okay, completed" ); // No tr - QCopEnvelope e("QPE/System", "linkChanged(QString)" ); - e << file.name(); - } else { - send( "550 Requested action not taken" ); // No tr - } - } + if ( args.isEmpty() ) + send( "500 Syntax error, command unrecognized" ); // No tr + else { + QFile file( absFilePath( args ) ) ; + if ( file.remove() ) { + send( "250 Requested file action okay, completed" ); // No tr + QCopEnvelope e("QPE/System", "linkChanged(QString)" ); + e << file.name(); + } else { + send( "550 Requested action not taken" ); // No tr + } + } } // remove directory (RMD) else if ( cmd == "RMD" ) { - if ( args.isEmpty() ) - send( "500 Syntax error, command unrecognized" ); // No tr - else { - QDir dir; - if ( dir.rmdir( absFilePath( args ), TRUE ) ) - send( "250 Requested file action okay, completed" ); // No tr - else - send( "550 Requested action not taken" ); // No tr - } + if ( args.isEmpty() ) + send( "500 Syntax error, command unrecognized" ); // No tr + else { + QDir dir; + if ( dir.rmdir( absFilePath( args ), TRUE ) ) + send( "250 Requested file action okay, completed" ); // No tr + else + send( "550 Requested action not taken" ); // No tr + } } // make directory (MKD) else if ( cmd == "MKD" ) { - if ( args.isEmpty() ) { + if ( args.isEmpty() ) { odebug << " Error: no arg" << oendl; - send( "500 Syntax error, command unrecognized" ); // No tr - } - else { - QDir dir; - if ( dir.mkdir( absFilePath( args ), TRUE ) ) - send( "250 Requested file action okay, completed." ); // No tr - else - send( "550 Requested action not taken" ); // No tr - } + send( "500 Syntax error, command unrecognized" ); // No tr + } + else { + QDir dir; + if ( dir.mkdir( absFilePath( args ), TRUE ) ) + send( "250 Requested file action okay, completed." ); // No tr + else + send( "550 Requested action not taken" ); // No tr + } } // print working directory (PWD) else if ( cmd == "PWD" ) { - send( "257 \"" + directory.path() +"\"" ); + send( "257 \"" + directory.path() +"\"" ); } // list (LIST) else if ( cmd == "LIST" ) { - if ( sendList( absFilePath( args ) ) ) - send( "150 File status okay" ); // No tr - else - send( "500 Syntax error, command unrecognized" ); // No tr + if ( sendList( absFilePath( args ) ) ) + send( "150 File status okay" ); // No tr + else + send( "500 Syntax error, command unrecognized" ); // No tr } // size (SIZE) else if ( cmd == "SIZE" ) { - QString filePath = absFilePath( args ); - QFileInfo fi( filePath ); - bool gzipfile = backupRestoreGzip( filePath ); - if ( !fi.exists() && !gzipfile ) - send( "500 Syntax error, command unrecognized" ); // No tr - else { - if ( !gzipfile ) - send( "213 " + QString::number( fi.size() ) ); - else { - Process duproc( QString("du") ); - duproc.addArgument("-s"); - QString in, out; - if ( !duproc.exec(in, out) ) { + QString filePath = absFilePath( args ); + QFileInfo fi( filePath ); + bool gzipfile = backupRestoreGzip( filePath ); + if ( !fi.exists() && !gzipfile ) + send( "500 Syntax error, command unrecognized" ); // No tr + else { + if ( !gzipfile ) + send( "213 " + QString::number( fi.size() ) ); + else { + Process duproc( QString("du") ); + duproc.addArgument("-s"); + QString in, out; + if ( !duproc.exec(in, out) ) { odebug << "du process failed; just sending back 1K" << oendl; - send( "213 1024"); - } - else { - QString size = out.left( out.find("\t") ); - int guess = size.toInt()/5; - if ( filePath.contains("doc") ) // No tr - guess *= 1000; + send( "213 1024"); + } + else { + QString size = out.left( out.find("\t") ); + int guess = size.toInt()/5; + if ( filePath.contains("doc") ) // No tr + guess *= 1000; odebug << "sending back gzip guess of " << guess << "" << oendl; - send( "213 " + QString::number(guess) ); - } - } - } + send( "213 " + QString::number(guess) ); + } + } + } } // name list (NLST) else if ( cmd == "NLST" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // site parameters (SITE) else if ( cmd == "SITE" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // system (SYST) else if ( cmd == "SYST" ) { - send( "215 UNIX Type: L8" ); // No tr + send( "215 UNIX Type: L8" ); // No tr } // status (STAT) else if ( cmd == "STAT" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // help (HELP ) else if ( cmd == "HELP" ) { - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr } // noop (NOOP) else if ( cmd == "NOOP" ) { - send( "200 Command okay" ); // No tr + send( "200 Command okay" ); // No tr } // not implemented else - send( "502 Command not implemented" ); // No tr + send( "502 Command not implemented" ); // No tr lastCommand = cmd; } bool ServerPI::backupRestoreGzip( const QString &file ) { return (file.find( "backup" ) != -1 && // No tr - file.findRev( ".tgz" ) == (int)file.length()-4 ); + file.findRev( ".tgz" ) == (int)file.length()-4 ); } bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets ) { if ( file.find( "backup" ) != -1 && // No tr file.findRev( ".tgz" ) == (int)file.length()-4 ) { QFileInfo info( file ); targets = info.dirPath( TRUE ); - qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(), - targets.join(" ").latin1() ); + odebug << "ServerPI::backupRestoreGzip for " << file.latin1() << " = " << targets.join(" ").latin1() << oendl; return true; } return false; } void ServerPI::sendFile( const QString& file ) { if ( passiv ) { - wait[SendFile] = TRUE; - waitfile = file; - if ( waitsocket ) - newConnection( waitsocket ); + wait[SendFile] = TRUE; + waitfile = file; + if ( waitsocket ) + newConnection( waitsocket ); } else { QStringList targets; if ( backupRestoreGzip( file, targets ) ) - dtp->sendGzipFile( file, targets, peeraddress, peerport ); + dtp->sendGzipFile( file, targets, peeraddress, peerport ); else dtp->sendFile( file, peeraddress, peerport ); } } void ServerPI::retrieveFile( const QString& file ) { if ( passiv ) { - wait[RetrieveFile] = TRUE; - waitfile = file; - if ( waitsocket ) - newConnection( waitsocket ); + wait[RetrieveFile] = TRUE; + waitfile = file; + if ( waitsocket ) + newConnection( waitsocket ); } else { QStringList targets; if ( backupRestoreGzip( file, targets ) ) - dtp->retrieveGzipFile( file, peeraddress, peerport ); + dtp->retrieveGzipFile( file, peeraddress, peerport ); else - dtp->retrieveFile( file, peeraddress, peerport, storFileSize ); + dtp->retrieveFile( file, peeraddress, peerport, storFileSize ); } } bool ServerPI::parsePort( const QString& pp ) { QStringList p = QStringList::split( ",", pp ); if ( p.count() != 6 ) return FALSE; // h1,h2,h3,h4,p1,p2 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + - ( p[2].toInt() << 8 ) + p[3].toInt() ); + ( p[2].toInt() << 8 ) + p[3].toInt() ); peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); return TRUE; } void ServerPI::dtpCompleted() { send( "226 Closing data connection, file transfer successful" ); // No tr if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) { - QString fn = dtp->fileName(); - if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { - QCopEnvelope e("QPE/System", "linkChanged(QString)" ); - e << fn; - } + QString fn = dtp->fileName(); + if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { + QCopEnvelope e("QPE/System", "linkChanged(QString)" ); + e << fn; + } } waitsocket = 0; dtp->close(); storFileSize = -1; } void ServerPI::dtpFailed() { dtp->close(); waitsocket = 0; send( "451 Requested action aborted: local error in processing" ); // No tr storFileSize = -1; } void ServerPI::dtpError( int ) { dtp->close(); waitsocket = 0; send( "451 Requested action aborted: local error in processing" ); // No tr storFileSize = -1; } bool ServerPI::sendList( const QString& arg ) { QByteArray listing; QBuffer buffer( listing ); if ( !buffer.open( IO_WriteOnly ) ) - return FALSE; + return FALSE; QTextStream ts( &buffer ); QString fn = arg; if ( fn.isEmpty() ) - fn = directory.path(); + fn = directory.path(); QFileInfo fi( fn ); if ( !fi.exists() ) return FALSE; // return file listing if ( fi.isFile() ) { - ts << fileListing( &fi ) << endl; + ts << fileListing( &fi ) << endl; } // return directory listing else if ( fi.isDir() ) { - QDir dir( fn ); - const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); + QDir dir( fn ); + const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); - QFileInfoListIterator it( *list ); - QFileInfo *info; + QFileInfoListIterator it( *list ); + QFileInfo *info; - unsigned long total = 0; - while ( ( info = it.current() ) ) { - if ( info->fileName() != "." && info->fileName() != ".." ) - total += info->size(); - ++it; - } + unsigned long total = 0; + while ( ( info = it.current() ) ) { + if ( info->fileName() != "." && info->fileName() != ".." ) + total += info->size(); + ++it; + } - ts << "total " << QString::number( total / 1024 ) << endl; // No tr + ts << "total " << QString::number( total / 1024 ) << endl; // No tr - it.toFirst(); - while ( ( info = it.current() ) ) { - if ( info->fileName() == "." || info->fileName() == ".." ) { - ++it; - continue; - } - ts << fileListing( info ) << endl; - ++it; - } + it.toFirst(); + while ( ( info = it.current() ) ) { + if ( info->fileName() == "." || info->fileName() == ".." ) { + ++it; + continue; + } + ts << fileListing( info ) << endl; + ++it; + } } if ( passiv ) { - waitarray = buffer.buffer(); - wait[SendByteArray] = TRUE; - if ( waitsocket ) - newConnection( waitsocket ); + waitarray = buffer.buffer(); + wait[SendByteArray] = TRUE; + if ( waitsocket ) + newConnection( waitsocket ); } else - dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); + dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); return TRUE; } QString ServerPI::fileListing( QFileInfo *info ) { if ( !info ) return QString::null; QString s; // type char if ( info->isDir() ) - s += "d"; + s += "d"; else if ( info->isSymLink() ) - s += "l"; + s += "l"; else - s += "-"; + s += "-"; // permisson string s += permissionString( info ) + " "; // number of hardlinks int subdirs = 1; if ( info->isDir() ) - subdirs = 2; + subdirs = 2; // FIXME : this is to slow //if ( info->isDir() ) //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count(); s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " "; // owner QString o = info->owner(); if ( o.isEmpty() ) - o = QString::number(info->ownerId()); + o = QString::number(info->ownerId()); s += o.leftJustify( 8, ' ', TRUE ) + " "; // group QString g = info->group(); if ( g.isEmpty() ) - g = QString::number(info->groupId()); + g = QString::number(info->groupId()); s += g.leftJustify( 8, ' ', TRUE ) + " "; // file size in bytes s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " "; // last modified date QDate date = info->lastModified().date(); QTime time = info->lastModified().time(); s += date.monthName( date.month() ) + " " - + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " " - + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":" - + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " "; + + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " " + + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":" + + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " "; // file name s += info->fileName(); return s; } QString ServerPI::permissionString( QFileInfo *info ) { if ( !info ) return QString( "---------" ); QString s; // user if ( info->permission( QFileInfo::ReadUser ) ) s += "r"; else s += "-"; if ( info->permission( QFileInfo::WriteUser ) ) s += "w"; else s += "-"; if ( info->permission( QFileInfo::ExeUser ) ) s += "x"; else s += "-"; // group if ( info->permission( QFileInfo::ReadGroup ) ) s += "r"; else s += "-"; if ( info->permission( QFileInfo::WriteGroup ) )s += "w"; else s += "-"; if ( info->permission( QFileInfo::ExeGroup ) ) s += "x"; else s += "-"; // exec if ( info->permission( QFileInfo::ReadOther ) ) s += "r"; else s += "-"; if ( info->permission( QFileInfo::WriteOther ) ) s += "w"; else s += "-"; if ( info->permission( QFileInfo::ExeOther ) ) s += "x"; else s += "-"; return s; } void ServerPI::newConnection( int socket ) { //odebug << "New incomming connection" << oendl; if ( !passiv ) return; if ( wait[SendFile] ) { - QStringList targets; - if ( backupRestoreGzip( waitfile, targets ) ) - dtp->sendGzipFile( waitfile, targets ); - else - dtp->sendFile( waitfile ); - dtp->setSocket( socket ); + QStringList targets; + if ( backupRestoreGzip( waitfile, targets ) ) + dtp->sendGzipFile( waitfile, targets ); + else + dtp->sendFile( waitfile ); + dtp->setSocket( socket ); } else if ( wait[RetrieveFile] ) { odebug << "check retrieve file" << oendl; if ( backupRestoreGzip( waitfile ) ) - dtp->retrieveGzipFile( waitfile ); + dtp->retrieveGzipFile( waitfile ); else - dtp->retrieveFile( waitfile, storFileSize ); + dtp->retrieveFile( waitfile, storFileSize ); dtp->setSocket( socket ); } else if ( wait[SendByteArray] ) { - dtp->sendByteArray( waitarray ); - dtp->setSocket( socket ); + dtp->sendByteArray( waitarray ); + dtp->setSocket( socket ); } else if ( wait[RetrieveByteArray] ) { odebug << "retrieve byte array" << oendl; - dtp->retrieveByteArray(); - dtp->setSocket( socket ); + dtp->retrieveByteArray(); + dtp->setSocket( socket ); } else - waitsocket = socket; + waitsocket = socket; for( int i = 0; i < 4; i++ ) - wait[i] = FALSE; + wait[i] = FALSE; } QString ServerPI::absFilePath( const QString& file ) { if ( file.isEmpty() ) return file; QString filepath( file ); if ( file[0] != "/" ) - filepath = directory.path() + "/" + file; + filepath = directory.path() + "/" + file; return filepath; } void ServerPI::timerEvent( QTimerEvent * ) { connectionClosed(); } ServerDTP::ServerDTP( QObject *parent, const char* name) : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), retrieveTargzProc( 0 ) { connect( this, SIGNAL( connected() ), SLOT( connected() ) ); connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); connect( this, SIGNAL( bytesWritten(int) ), SLOT( bytesWritten(int) ) ); connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); // No tr createTargzProc->setCommunication( QProcess::Stdout ); createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); retrieveTargzProc = new QProcess( this, "retrieveTargzProc" ); retrieveTargzProc->setCommunication( QProcess::Stdin ); retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); connect( retrieveTargzProc, SIGNAL( processExited() ), - SIGNAL( completed() ) ); + SIGNAL( completed() ) ); connect( retrieveTargzProc, SIGNAL( processExited() ), - SLOT( extractTarDone() ) ); + SLOT( extractTarDone() ) ); } ServerDTP::~ServerDTP() { buf.close(); if ( RetrieveFile == mode && file.isOpen() ) { - // We're being shutdown before the client closed. - file.close(); - if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { + // We're being shutdown before the client closed. + file.close(); + if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { odebug << "STOR incomplete" << oendl; - file.remove(); - } + file.remove(); + } } else { - file.close(); + file.close(); } createTargzProc->kill(); } void ServerDTP::extractTarDone() { odebug << "extract done" << oendl; #ifndef QT_NO_COP QCopEnvelope e( "QPE/System", "restoreDone(QString)" ); e << file.name(); #endif } void ServerDTP::connected() { // send file mode switch ( mode ) { case SendFile : if ( !file.exists() || !file.open( IO_ReadOnly) ) { emit failed(); mode = Idle; return; } //odebug << "Debug: Sending file '" << file.name() << "'" << oendl; bytes_written = 0; if ( file.size() == 0 ) { //make sure it doesn't hang on empty files file.close(); emit completed(); mode = Idle; } else { // Don't write more if there is plenty buffered already. if ( bytesToWrite() <= block_size && !file.atEnd() ) { - QCString s; - s.resize( block_size ); - int bytes = file.readBlock( s.data(), block_size ); - writeBlock( s.data(), bytes ); + QCString s; + s.resize( block_size ); + int bytes = file.readBlock( s.data(), block_size ); + writeBlock( s.data(), bytes ); } } break; case SendGzipFile: if ( createTargzProc->isRunning() ) { // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY owarn << "Previous tar --gzip process is still running; killing it..." << oendl; createTargzProc->kill(); } bytes_written = 0; odebug << "==>start send tar process" << oendl; if ( !createTargzProc->start() ) qWarning("Error starting %s", - createTargzProc->arguments().join(" ").latin1()); + createTargzProc->arguments().join(" ").latin1()); break; case SendBuffer: if ( !buf.open( IO_ReadOnly) ) { emit failed(); mode = Idle; return; } // odebug << "Debug: Sending byte array" << oendl; bytes_written = 0; while( !buf.atEnd() ) putch( buf.getch() ); buf.close(); break; case RetrieveFile: // retrieve file mode if ( file.exists() && !file.remove() ) { emit failed(); mode = Idle; return; } if ( !file.open( IO_WriteOnly) ) { emit failed(); mode = Idle; return; } // odebug << "Debug: Retrieving file " << file.name() << "" << oendl; break; case RetrieveGzipFile: odebug << "=-> starting tar process to receive .tgz file" << oendl; break; case RetrieveBuffer: // retrieve buffer mode if ( !buf.open( IO_WriteOnly) ) { emit failed(); mode = Idle; return; } // odebug << "Debug: Retrieving byte array" << oendl; break; case Idle: odebug << "connection established but mode set to Idle; BUG!" << oendl; break; } } void ServerDTP::connectionClosed() { //odebug << "Debug: Data connection closed " << bytes_written << " bytes written" << oendl; // send file mode if ( SendFile == mode ) { - if ( bytes_written == file.size() ) - emit completed(); - else - emit failed(); + if ( bytes_written == file.size() ) + emit completed(); + else + emit failed(); } // send buffer mode else if ( SendBuffer == mode ) { - if ( bytes_written == buf.size() ) - emit completed(); - else - emit failed(); + if ( bytes_written == buf.size() ) + emit completed(); + else + emit failed(); } // retrieve file mode else if ( RetrieveFile == mode ) { - file.close(); - if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { + file.close(); + if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { odebug << "STOR incomplete" << oendl; - file.remove(); - emit failed(); - } else { - emit completed(); - } + file.remove(); + emit failed(); + } else { + emit completed(); + } } else if ( RetrieveGzipFile == mode ) { odebug << "Done writing ungzip file; closing input" << oendl; - retrieveTargzProc->flushStdin(); - retrieveTargzProc->closeStdin(); + retrieveTargzProc->flushStdin(); + retrieveTargzProc->closeStdin(); } // retrieve buffer mode else if ( RetrieveBuffer == mode ) { - buf.close(); - emit completed(); + buf.close(); + emit completed(); } mode = Idle; } void ServerDTP::bytesWritten( int bytes ) { bytes_written += bytes; // send file mode if ( SendFile == mode ) { - if ( bytes_written == file.size() ) { + if ( bytes_written == file.size() ) { // odebug << "Debug: Sending complete: " << file.size() << " bytes" << oendl; - file.close(); - emit completed(); - mode = Idle; - } - else if( !file.atEnd() ) { - QCString s; - s.resize( block_size ); - int bytes = file.readBlock( s.data(), block_size ); - writeBlock( s.data(), bytes ); - } + file.close(); + emit completed(); + mode = Idle; + } + else if( !file.atEnd() ) { + QCString s; + s.resize( block_size ); + int bytes = file.readBlock( s.data(), block_size ); + writeBlock( s.data(), bytes ); + } } // send buffer mode if ( SendBuffer == mode ) { - if ( bytes_written == buf.size() ) { + if ( bytes_written == buf.size() ) { // odebug << "Debug: Sending complete: " << buf.size() << " bytes" << oendl; - emit completed(); - mode = Idle; - } + emit completed(); + mode = Idle; + } } } void ServerDTP::readyRead() { // retrieve file mode if ( RetrieveFile == mode ) { - QCString s; - s.resize( bytesAvailable() ); - readBlock( s.data(), bytesAvailable() ); - file.writeBlock( s.data(), s.size() ); + QCString s; + s.resize( bytesAvailable() ); + readBlock( s.data(), bytesAvailable() ); + file.writeBlock( s.data(), s.size() ); } else if ( RetrieveGzipFile == mode ) { - if ( !retrieveTargzProc->isRunning() ) - retrieveTargzProc->start(); + if ( !retrieveTargzProc->isRunning() ) + retrieveTargzProc->start(); - QByteArray s; - s.resize( bytesAvailable() ); - readBlock( s.data(), bytesAvailable() ); - retrieveTargzProc->writeToStdin( s ); + QByteArray s; + s.resize( bytesAvailable() ); + readBlock( s.data(), bytesAvailable() ); + retrieveTargzProc->writeToStdin( s ); odebug << "wrote " << s.size() << " bytes to ungzip " << oendl; } // retrieve buffer mode else if ( RetrieveBuffer == mode ) { - QCString s; - s.resize( bytesAvailable() ); - readBlock( s.data(), bytesAvailable() ); - buf.writeBlock( s.data(), s.size() ); + QCString s; + s.resize( bytesAvailable() ); + readBlock( s.data(), bytesAvailable() ); + buf.writeBlock( s.data(), s.size() ); } } void ServerDTP::writeTargzBlock() { QByteArray block = createTargzProc->readStdout(); writeBlock( block.data(), block.size() ); odebug << "writeTargzBlock " << block.size() << "" << oendl; } void ServerDTP::targzDone() { odebug << "tar and gzip done" << oendl; emit completed(); mode = Idle; disconnect( createTargzProc, SIGNAL( readyReadStdout() ), - this, SLOT( writeTargzBlock() ) ); + this, SLOT( writeTargzBlock() ) ); } void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) { file.setName( fn ); mode = SendFile; connectToHost( host.toString(), port ); } void ServerDTP::sendFile( const QString fn ) { file.setName( fn ); mode = SendFile; } void ServerDTP::sendGzipFile( const QString &fn, - const QStringList &archiveTargets, - const QHostAddress& host, Q_UINT16 port ) + const QStringList &archiveTargets, + const QHostAddress& host, Q_UINT16 port ) { sendGzipFile( fn, archiveTargets ); connectToHost( host.toString(), port ); } void ServerDTP::sendGzipFile( const QString &fn, - const QStringList &archiveTargets ) + const QStringList &archiveTargets ) { mode = SendGzipFile; file.setName( fn ); QStringList args = "targzip"; //args += "-cv"; args += archiveTargets; odebug << "sendGzipFile " << args.join(" ") << "" << oendl; createTargzProc->setArguments( args ); connect( createTargzProc, - SIGNAL( readyReadStdout() ), SLOT( writeTargzBlock() ) ); + SIGNAL( readyReadStdout() ), SLOT( writeTargzBlock() ) ); } void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port, int fileSize ) { recvFileSize = fileSize; file.setName( fn ); mode = RetrieveFile; connectToHost( host.toString(), port ); } void ServerDTP::retrieveFile( const QString fn, int fileSize ) { recvFileSize = fileSize; file.setName( fn ); mode = RetrieveFile; } void ServerDTP::retrieveGzipFile( const QString &fn ) { odebug << "retrieveGzipFile " << fn << "" << oendl; file.setName( fn ); mode = RetrieveGzipFile; retrieveTargzProc->setArguments( "targunzip" ); connect( retrieveTargzProc, SIGNAL( processExited() ), - SLOT( extractTarDone() ) ); + SLOT( extractTarDone() ) ); } void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port ) { retrieveGzipFile( fn ); connectToHost( host.toString(), port ); } void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port ) { buf.setBuffer( array ); mode = SendBuffer; connectToHost( host.toString(), port ); } void ServerDTP::sendByteArray( const QByteArray& array ) { buf.setBuffer( array ); mode = SendBuffer; } void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port ) { buf.setBuffer( QByteArray() ); mode = RetrieveBuffer; connectToHost( host.toString(), port ); } void ServerDTP::retrieveByteArray() { buf.setBuffer( QByteArray() ); mode = RetrieveBuffer; } void ServerDTP::setSocket( int socket ) { QSocket::setSocket( socket ); connected(); } |