-rw-r--r-- | core/launcher/applauncher.cpp | 11 | ||||
-rw-r--r-- | core/launcher/config.in | 6 | ||||
-rw-r--r-- | core/launcher/documentlist.cpp | 11 | ||||
-rw-r--r-- | core/launcher/main.cpp | 9 | ||||
-rw-r--r-- | core/launcher/qcopbridge.cpp | 7 | ||||
-rw-r--r-- | core/launcher/screensaver.cpp | 2 | ||||
-rw-r--r-- | core/launcher/server.cpp | 4 | ||||
-rw-r--r-- | core/launcher/server.pro | 7 | ||||
-rw-r--r-- | core/launcher/startmenu.cpp | 2 | ||||
-rw-r--r-- | core/launcher/transferserver.cpp | 27 | ||||
-rw-r--r-- | core/launcher/wait.cpp | 2 |
11 files changed, 45 insertions, 43 deletions
diff --git a/core/launcher/applauncher.cpp b/core/launcher/applauncher.cpp index 0db99dd..f161e98 100644 --- a/core/launcher/applauncher.cpp +++ b/core/launcher/applauncher.cpp @@ -1,725 +1,724 @@ /********************************************************************** ** 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. ** **********************************************************************/ #ifndef QTOPIA_INTERNAL_PRELOADACCESS #define QTOPIA_INTERNAL_PRELOADACCESS #endif #ifndef QTOPIA_INTERNAL_FILEOPERATIONS #define QTOPIA_INTERNAL_FILEOPERATIONS #endif #ifndef QTOPIA_PROGRAM_MONITOR #define QTOPIA_PROGRAM_MONITOR #endif -#include <qtopia/global.h> +#include <opie2/oglobal.h> #ifndef Q_OS_WIN32 #include <sys/stat.h> #include <sys/wait.h> #include <sys/file.h> #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> #include <errno.h> #else #include <process.h> #include <windows.h> #include <winbase.h> #endif #include <signal.h> #include <sys/types.h> #include <stdlib.h> #include <qtimer.h> #include <qwindowsystem_qws.h> #include <qmessagebox.h> #include <qfile.h> #include <qfileinfo.h> #include <qtopia/qcopenvelope_qws.h> #include <qtopia/applnk.h> #include <qtopia/qpeapplication.h> #include <qtopia/config.h> #include <qtopia/global.h> #include "applauncher.h" #include "documentlist.h" -#include "launcherglobal.h" const int AppLauncher::RAISE_TIMEOUT_MS = 5000; //--------------------------------------------------------------------------- static AppLauncher* appLauncherPtr; const int appStopEventID = 1290; class AppStoppedEvent : public QCustomEvent { public: AppStoppedEvent(int pid, int status) : QCustomEvent( appStopEventID ), mPid(pid), mStatus(status) { } int pid() { return mPid; } int status() { return mStatus; } private: int mPid, mStatus; }; AppLauncher::AppLauncher(QObject *parent, const char *name) : QObject(parent, name), qlPid(0), qlReady(FALSE), appKillerBox(0) { connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&))); QCopChannel* channel = new QCopChannel( "QPE/System", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(received(const QCString&, const QByteArray&)) ); channel = new QCopChannel( "QPE/Server", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(received(const QCString&, const QByteArray&)) ); #ifndef Q_OS_WIN32 signal(SIGCHLD, signalHandler); #else runningAppsProc.setAutoDelete( TRUE ); #endif QString tmp = qApp->argv()[0]; int pos = tmp.findRev('/'); if ( pos > -1 ) tmp = tmp.mid(++pos); runningApps[::getpid()] = tmp; appLauncherPtr = this; QTimer::singleShot( 1000, this, SLOT(createQuickLauncher()) ); } AppLauncher::~AppLauncher() { appLauncherPtr = 0; #ifndef Q_OS_WIN32 signal(SIGCHLD, SIG_DFL); #endif if ( qlPid ) { int status; ::kill( qlPid, SIGTERM ); waitpid( qlPid, &status, 0 ); } } /* We use the QCopChannel of the app as an indicator of when it has been launched so that we can disable the busy indicators */ void AppLauncher::newQcopChannel(const QString& channelName) { // qDebug("channel %s added", channelName.data() ); QString prefix("QPE/Application/"); if (channelName.startsWith(prefix)) { { QCopEnvelope e("QPE/System", "newChannel(QString)"); e << channelName; } QString appName = channelName.mid(prefix.length()); if ( appName != "quicklauncher" ) { emit connected( appName ); QCopEnvelope e("QPE/System", "notBusy(QString)"); e << appName; } } else if (channelName.startsWith("QPE/QuickLauncher-")) { qDebug("Registered %s", channelName.latin1()); int pid = channelName.mid(18).toInt(); if (pid == qlPid) qlReady = TRUE; } } void AppLauncher::removedQcopChannel(const QString& channelName) { if (channelName.startsWith("QPE/Application/")) { QCopEnvelope e("QPE/System", "removedChannel(QString)"); e << channelName; } } void AppLauncher::received(const QCString& msg, const QByteArray& data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "execute(QString)" ) { QString t; stream >> t; if ( !executeBuiltin( t, QString::null ) ) execute(t, QString::null); } else if ( msg == "execute(QString,QString)" ) { QString t,d; stream >> t >> d; if ( !executeBuiltin( t, d ) ) execute( t, d ); } else if ( msg == "processQCop(QString)" ) { // from QPE/Server QString t; stream >> t; if ( !executeBuiltin( t, QString::null ) ) execute( t, QString::null, TRUE); } else if ( msg == "raise(QString)" ) { QString appName; stream >> appName; if ( !executeBuiltin( appName, QString::null ) ) { if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { //qDebug( "Raising: %s", appName.latin1() ); QCString channel = "QPE/Application/"; channel += appName.latin1(); // Need to lock it to avoid race conditions with QPEApplication::processQCopFile QFile f("/tmp/qcop-msg-" + appName); if ( f.open(IO_WriteOnly | IO_Append) ) { #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_EX); #endif QDataStream ds(&f); QByteArray b; QDataStream bstream(b, IO_WriteOnly); ds << channel << QCString("raise()") << b; f.flush(); #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_UN); #endif f.close(); } bool alreadyRunning = isRunning( appName ); if ( execute(appName, QString::null) ) { int id = startTimer(RAISE_TIMEOUT_MS + alreadyRunning?2000:0); waitingHeartbeat.insert( appName, id ); } } } } else if ( msg == "sendRunningApps()" ) { QStringList apps; QMap<int,QString>::Iterator it; for( it = runningApps.begin(); it != runningApps.end(); ++it ) apps.append( *it ); QCopEnvelope e( "QPE/Desktop", "runningApps(QStringList)" ); e << apps; } else if ( msg == "appRaised(QString)" ) { QString appName; stream >> appName; qDebug("Got a heartbeat from %s", appName.latin1()); QMap<QString,int>::Iterator it = waitingHeartbeat.find(appName); if ( it != waitingHeartbeat.end() ) { killTimer( *it ); waitingHeartbeat.remove(it); } // Check to make sure we're not waiting on user input... if ( appKillerBox && appName == appKillerName ) { // If we are, we kill the dialog box, and the code waiting on the result // will clean us up (basically the user said "no"). delete appKillerBox; appKillerBox = 0; appKillerName = QString::null; } } } void AppLauncher::signalHandler(int) { #ifndef Q_OS_WIN32 int status; pid_t pid = waitpid(-1, &status, WNOHANG); /* if (pid == 0 || &status == 0 ) { qDebug("hmm, could not get return value from signal"); } */ QApplication::postEvent(appLauncherPtr, new AppStoppedEvent(pid, status) ); #else qDebug("Unhandled signal see by AppLauncher::signalHandler(int)"); #endif } bool AppLauncher::event(QEvent *e) { if ( e->type() == appStopEventID ) { AppStoppedEvent *ae = (AppStoppedEvent *) e; sigStopped(ae->pid(), ae->status() ); return TRUE; } return QObject::event(e); } void AppLauncher::timerEvent( QTimerEvent *e ) { int id = e->timerId(); QMap<QString,int>::Iterator it; for ( it = waitingHeartbeat.begin(); it != waitingHeartbeat.end(); ++it ) { if ( *it == id ) { if ( appKillerBox ) // we're already dealing with one return; appKillerName = it.key(); killTimer( id ); waitingHeartbeat.remove( it ); // qDebug("Checking in on %s", appKillerName.latin1()); // We store this incase the application responds while we're // waiting for user input so we know not to delete ourselves. appKillerBox = new QMessageBox(tr("Application Problem"), tr("<p>%1 is not responding.</p>").arg(appKillerName) + tr("<p>Would you like to force the application to exit?</p>"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default, QMessageBox::NoButton); if (appKillerBox->exec() == QMessageBox::Yes) { // qDebug("Killing the app!!! Bwuhahahaha!"); int pid = pidForName(appKillerName); if ( pid > 0 ) kill( pid ); } appKillerName = QString::null; delete appKillerBox; appKillerBox = 0; return; } } QObject::timerEvent( e ); } #ifndef Q_OS_WIN32 void AppLauncher::sigStopped(int sigPid, int sigStatus) { int exitStatus = 0; bool crashed = WIFSIGNALED(sigStatus); if ( !crashed ) { if ( WIFEXITED(sigStatus) ) exitStatus = WEXITSTATUS(sigStatus); } else { exitStatus = WTERMSIG(sigStatus); } QMap<int,QString>::Iterator it = runningApps.find( sigPid ); if ( it == runningApps.end() ) { if ( sigPid == qlPid ) { qDebug( "quicklauncher stopped" ); qlPid = 0; qlReady = FALSE; QFile::remove("/tmp/qcop-msg-quicklauncher" ); QTimer::singleShot( 2000, this, SLOT(createQuickLauncher()) ); } /* if ( sigPid == -1 ) qDebug("non-qtopia application exited (disregarded)"); else qDebug("==== no pid matching %d in list, definite bug", sigPid); */ return; } QString appName = *it; runningApps.remove(it); QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); if ( hbit != waitingHeartbeat.end() ) { killTimer( *hbit ); waitingHeartbeat.remove( hbit ); } if ( appName == appKillerName ) { appKillerName = QString::null; delete appKillerBox; appKillerBox = 0; } /* we must disable preload for an app that crashes as the system logic relies on preloaded apps actually being loaded. If eg. the crash happened in the constructor, we can't automatically reload the app (withouth some timeout value for eg. 3 tries (which I think is a bad solution) */ bool preloadDisabled = FALSE; if ( !DocumentList::appLnkSet ) return; const AppLnk* app = DocumentList::appLnkSet->findExec( appName ); if ( !app ) return; // QCop messages processed to slow? if ( crashed && app->isPreloaded() ) { Config cfg("Launcher"); cfg.setGroup("Preload"); QStringList apps = cfg.readListEntry("Apps",','); QString exe = app->exec(); apps.remove(exe); cfg.writeEntry("Apps",apps,','); preloadDisabled = TRUE; } // clean up if ( exitStatus ) { QCopEnvelope e("QPE/System", "notBusy(QString)"); e << app->exec(); } /* // debug info for (it = runningApps.begin(); it != runningApps.end(); ++it) { qDebug("running according to internal list: %s, with pid %d", (*it).data(), it.key() ); } */ #ifdef QTOPIA_PROGRAM_MONITOR if ( crashed ) { QString sig; switch( exitStatus ) { case SIGABRT: sig = "SIGABRT"; break; case SIGALRM: sig = "SIGALRM"; break; case SIGBUS: sig = "SIGBUS"; break; case SIGFPE: sig = "SIGFPE"; break; case SIGHUP: sig = "SIGHUP"; break; case SIGILL: sig = "SIGILL"; break; case SIGKILL: sig = "SIGKILL"; break; case SIGPIPE: sig = "SIGPIPE"; break; case SIGQUIT: sig = "SIGQUIT"; break; case SIGSEGV: sig = "SIGSEGV"; break; case SIGTERM: sig = "SIGTERM"; break; case SIGTRAP: sig = "SIGTRAP"; break; default: sig = QString("Unkown %1").arg(exitStatus); } if ( preloadDisabled ) sig += tr("<qt><p>Fast loading has been disabled for this application. Tap and hold the application icon to reenable it.</qt>"); QString str = tr("<qt><b>%1</b> was terminated due to signal code %2</qt>").arg( app->name() ).arg( sig ); QMessageBox::information(0, tr("Application terminated"), str ); } else { if ( exitStatus == 255 ) { //could not find app (because global returns -1) QMessageBox::information(0, tr("Application not found"), tr("<qt>Could not locate application <b>%1</b></qt>").arg( app->exec() ) ); } else { - QFileInfo fi(Opie::Global::tempDir() + "qcop-msg-" + appName); + QFileInfo fi(OGlobal::tempDirPath() + "qcop-msg-" + appName); if ( fi.exists() && fi.size() ) { emit terminated(sigPid, appName); qWarning("Re executing obmitted for %s", appName.latin1() ); // execute( appName, QString::null ); return; } } } #endif emit terminated(sigPid, appName); } #else void AppLauncher::sigStopped(int sigPid, int sigStatus) { qDebug("Unhandled signal : AppLauncher::sigStopped(int sigPid, int sigStatus)"); } #endif // Q_OS_WIN32 bool AppLauncher::isRunning(const QString &app) { for (QMap<int,QString>::ConstIterator it = runningApps.begin(); it != runningApps.end(); ++it) { if ( *it == app ) { #ifdef Q_OS_UNIX pid_t t = ::__getpgid( it.key() ); if ( t == -1 ) { qDebug("appLauncher bug, %s believed running, but pid %d is not existing", app.data(), it.key() ); runningApps.remove( it.key() ); return FALSE; } #endif return TRUE; } } return FALSE; } bool AppLauncher::executeBuiltin(const QString &c, const QString &document) { - Global::Command* builtin = Opie::Global::builtinCommands(); - QGuardedPtr<QWidget> *running = Opie::Global::builtinRunning(); + Global::Command* builtin = OGlobal::builtinCommands(); + QGuardedPtr<QWidget> *running = OGlobal::builtinRunning(); // Attempt to execute the app using a builtin class for the app if (builtin) { for (int i = 0; builtin[i].file; i++) { if ( builtin[i].file == c ) { if ( running[i] ) { if ( !document.isNull() && builtin[i].documentary ) Global::setDocument(running[i], document); running[i]->raise(); running[i]->show(); running[i]->setActiveWindow(); } else { running[i] = builtin[i].func( builtin[i].maximized ); } #ifndef QT_NO_COP QCopEnvelope e("QPE/System", "notBusy(QString)" ); e << c; // that was quick ;-) #endif return TRUE; } } } // Convert the command line in to a list of arguments QStringList list = QStringList::split(QRegExp(" *"),c); QString ap=list[0]; if ( ap == "suspend" ) { // No tr QWSServer::processKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); return TRUE; } return FALSE; } bool AppLauncher::execute(const QString &c, const QString &docParam, bool noRaise) { qWarning("AppLauncher::execute"); // Convert the command line in to a list of arguments QStringList list = QStringList::split(QRegExp(" *"),c); if ( !docParam.isEmpty() ) list.append( docParam ); QString appName = list[0]; if ( isRunning(appName) ) { QCString channel = "QPE/Application/"; channel += appName.latin1(); // Need to lock it to avoid race conditions with QPEApplication::processQCopFile - QFile f(Opie::Global::tempDir() + "qcop-msg-" + appName); + QFile f(OGlobal::tempDirPath() + "qcop-msg-" + appName); if ( !noRaise && f.open(IO_WriteOnly | IO_Append) ) { #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_EX); #endif QDataStream ds(&f); QByteArray b; QDataStream bstream(b, IO_WriteOnly); if ( !f.size() ) { ds << channel << QCString("raise()") << b; if ( !waitingHeartbeat.contains( appName ) && appKillerName != appName ) { int id = startTimer(RAISE_TIMEOUT_MS); waitingHeartbeat.insert( appName, id ); } } if ( !docParam.isEmpty() ) { bstream << docParam; ds << channel << QCString("setDocument(QString)") << b; } f.flush(); #ifndef Q_OS_WIN32 flock(f.handle(), LOCK_UN); #endif f.close(); } if ( QCopChannel::isRegistered(channel) ) // avoid unnecessary warnings QCopChannel::send(channel,"QPEProcessQCop()"); return TRUE; } #ifdef QT_NO_QWS_MULTIPROCESS QMessageBox::warning( 0, tr("Error"), tr("<qt>Could not find the application %1</qt>").arg(c), tr("OK"), 0, 0, 0, 1 ); #else QStrList slist; unsigned j; for ( j = 0; j < list.count(); j++ ) slist.append( list[j].utf8() ); const char **args = new const char *[slist.count() + 1]; for ( j = 0; j < slist.count(); j++ ) args[j] = slist.at(j); args[j] = NULL; #ifndef Q_OS_WIN32 #ifdef Q_OS_MACX if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".dylib" ) ) { #else if ( qlPid && qlReady && QFile::exists( QPEApplication::qpeDir()+"plugins/application/lib"+args[0] + ".so" ) ) { #endif /* Q_OS_MACX */ qDebug( "Quick launching: %s", args[0] ); if ( getuid() == 0 ) setpriority( PRIO_PROCESS, qlPid, 0 ); QCString qlch("QPE/QuickLauncher-"); qlch += QString::number(qlPid); QCopEnvelope env( qlch, "execute(QStrList)" ); env << slist; runningApps[qlPid] = QString(args[0]); emit launched(qlPid, QString(args[0])); QCopEnvelope e("QPE/System", "busy()"); qlPid = 0; qlReady = FALSE; QTimer::singleShot( getuid() == 0 ? 800 : 1500, this, SLOT(createQuickLauncher()) ); } else { int pid = ::vfork(); if ( !pid ) { for ( int fd = 3; fd < 100; fd++ ) ::close( fd ); ::setpgid( ::getpid(), ::getppid() ); // Try bindir first, so that foo/bar works too ::execv( QPEApplication::qpeDir()+"bin/"+args[0], (char * const *)args ); ::execvp( args[0], (char * const *)args ); _exit( -1 ); } runningApps[pid] = QString(args[0]); emit launched(pid, QString(args[0])); QCopEnvelope e("QPE/System", "busy()"); } #else QProcess *proc = new QProcess(this); if (proc){ for (int i=0; i < slist.count(); i++) proc->addArgument(args[i]); connect(proc, SIGNAL(processExited()), this, SLOT(processExited())); if (!proc->start()){ qDebug("Unable to start application %s", args[0]); }else{ PROCESS_INFORMATION *procInfo = (PROCESS_INFORMATION *)proc->processIdentifier(); if (procInfo){ DWORD pid = procInfo->dwProcessId; runningApps[pid] = QString(args[0]); runningAppsProc.append(proc); emit launched(pid, QString(args[0])); QCopEnvelope e("QPE/System", "busy()"); }else{ qDebug("Unable to read process inforation #1 for %s", args[0]); } } }else{ qDebug("Unable to create process for application %s", args[0]); return FALSE; } #endif #endif //QT_NO_QWS_MULTIPROCESS delete [] args; return TRUE; } void AppLauncher::kill( int pid ) { #ifndef Q_OS_WIN32 ::kill( pid, SIGTERM ); #else for ( QProcess *proc = runningAppsProc.first(); proc; proc = runningAppsProc.next() ) { if ( proc->processIdentifier() == pid ) { proc->kill(); break; } } #endif } int AppLauncher::pidForName( const QString &appName ) { int pid = -1; QMap<int, QString>::Iterator it; for (it = runningApps.begin(); it!= runningApps.end(); ++it) { if (*it == appName) { pid = it.key(); break; } } return pid; } void AppLauncher::createQuickLauncher() { static bool disabled = FALSE; if (disabled) return; qlReady = FALSE; qlPid = ::vfork(); if ( !qlPid ) { char **args = new char *[2]; args[0] = "quicklauncher"; args[1] = 0; for ( int fd = 3; fd < 100; fd++ ) ::close( fd ); ::setpgid( ::getpid(), ::getppid() ); // Try bindir first, so that foo/bar works too /* * LD_BIND_NOW will change the behaviour of ld.so and dlopen * RTLD_LAZY will be made RTLD_NOW which leads to problem * with miscompiled libraries... if LD_BIND_NOW is set.. there * is no way back.. We will wait for numbers from TT to see * if using LD_BIND_NOW is worth it - zecke */ // setenv( "LD_BIND_NOW", "1", 1 ); ::execv( QPEApplication::qpeDir()+"bin/quicklauncher", args ); ::execvp( "quicklauncher", args ); delete []args; disabled = TRUE; _exit( -1 ); } else if ( qlPid == -1 ) { qlPid = 0; } else { if ( getuid() == 0 ) setpriority( PRIO_PROCESS, qlPid, 19 ); } } // Used only by Win32 void AppLauncher::processExited() { #ifdef Q_OS_WIN32 qDebug("AppLauncher::processExited()"); bool found = FALSE; QProcess *proc = (QProcess *) sender(); if (!proc){ qDebug("Interanl error NULL proc"); return; } QString appName = proc->arguments()[0]; qDebug("Removing application %s", appName.latin1()); runningAppsProc.remove(proc); QMap<QString,int>::Iterator hbit = waitingHeartbeat.find(appName); if ( hbit != waitingHeartbeat.end() ) { killTimer( *hbit ); waitingHeartbeat.remove( hbit ); } if ( appName == appKillerName ) { appKillerName = QString::null; delete appKillerBox; appKillerBox = 0; } // Search for the app to find its PID QMap<int, QString>::Iterator it; for (it = runningApps.begin(); it!= runningApps.end(); ++it){ if (it.data() == appName){ found = TRUE; break; } } if (found){ emit terminated(it.key(), it.data()); runningApps.remove(it.key()); }else{ qDebug("Internal error application %s not listed as running", appName.latin1()); } #endif } diff --git a/core/launcher/config.in b/core/launcher/config.in index 2d9c1c2..db39210 100644 --- a/core/launcher/config.in +++ b/core/launcher/config.in @@ -1,16 +1,16 @@ config LAUNCHER boolean "opie-taskbar (program launcher qpe for Opie)" default "y" - depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2CORE && LIBOPIE2UI if LAUNCHER config PRELOAD boolean default "y" - depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE && LAUNCHER + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2UI && LAUNCHER config LAUNCHER_CORE boolean default "y" - depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE && LAUNCHER && PRELOAD + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE2UI && LAUNCHER && PRELOAD endif diff --git a/core/launcher/documentlist.cpp b/core/launcher/documentlist.cpp index ece6931..440bf1e 100644 --- a/core/launcher/documentlist.cpp +++ b/core/launcher/documentlist.cpp @@ -1,652 +1,655 @@ /********************************************************************** ** 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 "documentlist.h" #include "serverinterface.h" -#include "launcherglobal.h" + +#include <opie2/oglobal.h> #include <qtopia/config.h> #include <qtopia/mimetype.h> #include <qtopia/resource.h> -#include <qtopia/global.h> #include <qtopia/private/categories.h> #include <qtopia/qpeapplication.h> #include <qtopia/applnk.h> #include <qtopia/storage.h> #ifdef Q_WS_QWS #include <qtopia/qcopenvelope_qws.h> #endif #include <qtimer.h> #include <qfileinfo.h> #include <qtextstream.h> #include <qfile.h> #include <qdir.h> #include <qpainter.h> #include <qimage.h> #include <qcopchannel_qws.h> #include <qlistview.h> #include <qlist.h> #include <qpixmap.h> AppLnkSet *DocumentList::appLnkSet = 0; static const int MAX_SEARCH_DEPTH = 10; class DocumentListPrivate : public QObject { Q_OBJECT public: DocumentListPrivate( ServerInterface *gui ); ~DocumentListPrivate(); void initialize(); const QString nextFile(); const DocLnk *iterate(); bool store( DocLnk* dl ); void estimatedPercentScanned(); DocLnkSet dls; QDict<void> reference; QDictIterator<void> *dit; enum { Find, RemoveKnownFiles, MakeUnknownFiles, Done } state; QStringList docPaths; unsigned int docPathsSearched; int searchDepth; QDir *listDirs[MAX_SEARCH_DEPTH]; const QFileInfoList *lists[MAX_SEARCH_DEPTH]; unsigned int listPositions[MAX_SEARCH_DEPTH]; StorageInfo *storage; int tid; ServerInterface *serverGui; bool needToSendAllDocLinks; bool sendAppLnks; bool sendDocLnks; bool scanDocs; }; -DocumentList::DocumentList( ServerInterface *serverGui, bool scanDocs, +/* + * scandocs will be read from Config + */ +DocumentList::DocumentList( ServerInterface *serverGui, bool /*scanDocs*/, QObject *parent, const char *name ) : QObject( parent, name ) { appLnkSet = new AppLnkSet( MimeType::appsFolderName() ); d = new DocumentListPrivate( serverGui ); d->needToSendAllDocLinks = false; Config cfg( "Launcher" ); cfg.setGroup( "DocTab" ); d->scanDocs = cfg.readBoolEntry( "Enable", true ); qDebug( "DocumentList::DocumentList() : scanDocs = %d", d->scanDocs ); QTimer::singleShot( 10, this, SLOT( startInitialScan() ) ); } void DocumentList::startInitialScan() { reloadAppLnks(); reloadDocLnks(); } DocumentList::~DocumentList() { delete appLnkSet; delete d; } void DocumentList::add( const DocLnk& doc ) { if ( d->serverGui && QFile::exists( doc.file() ) ) d->serverGui->documentAdded( doc ); } void DocumentList::start() { resume(); } void DocumentList::pause() { //qDebug("pause %i", d->tid); killTimer( d->tid ); d->tid = 0; } void DocumentList::resume() { if ( d->tid == 0 ) { d->tid = startTimer( 20 ); //qDebug("resumed %i", d->tid); } } /* 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() { //qDebug("rescan"); pause(); d->initialize(); resume(); } void DocumentList::timerEvent( QTimerEvent *te ) { if ( te->timerId() == d->tid ) { // Do 3 at a time 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; } } } } 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() ); } //qDebug("adding type %s", (*ittypes).latin1()); // ### 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) { //qDebug("removing type %s", (*ittypes).latin1()); 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 ) { //qDebug( "linkchanged( %s )", arg.latin1() ); - if ( arg.isNull() || Opie::Global::isAppLnkFileName( arg ) ) { + 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 ) ) { //qDebug( "found old link" ); 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 //qDebug( "change case" ); 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 //qDebug( "removal case" ); 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 //qDebug( "add case" ); add( *dl ); } } } void DocumentList::restoreDone() { reloadAppLnks(); reloadDocLnks(); } void DocumentList::storageChanged() { // ### can implement better reloadAppLnks(); reloadDocLnks(); // ### 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 } //qDebug( "sending length %d", contents.length() ); #ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" ); e << contents; #endif //qDebug( "================ \n\n%s\n\n===============", contents.latin1() ); 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::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() ) { docPaths += (*it)->path(); 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; } } // qDebug( "overallProgress: %f", overallProgress ); 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] ); // qDebug("now using base path: %s", docPaths[docPathsSearched].latin1() ); 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]; 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() ); // qDebug("now going in to path: %s", bn.latin1() ); if ( !dir.exists( ".Qtopia-ignore" ) ) { if ( searchDepth < MAX_SEARCH_DEPTH - 1) { searchDepth++; listDirs[searchDepth] = new QDir( dir ); lists[searchDepth] = listDirs[searchDepth]->entryInfoList(); listPositions[searchDepth] = 0; } } } } else { estimatedPercentScanned(); return fl->at(pos)->filePath(); } } } } return QString::null; } bool DocumentListPrivate::store( DocLnk* dl ) { // if ( dl->fileKnown() && !dl->file().isEmpty() ) { if ( dl && dl->fileKnown() ) { dls.add( dl ); // store return TRUE; } // don't store - delete delete dl; return FALSE; } #define MAGIC_NUMBER ((void*)2) const DocLnk *DocumentListPrivate::iterate() { if ( state == Find ) { //qDebug("state Find"); QString file = nextFile(); while ( !file.isNull() ) { if ( file.right(8) == ".desktop" ) { // No tr DocLnk* dl = new DocLnk( file ); if ( store(dl) ) return dl; } else { reference.insert( file, MAGIC_NUMBER ); } file = nextFile(); } state = RemoveKnownFiles; if ( serverGui ) serverGui->documentScanningProgress( 75 ); } static int iterationI; static int iterationCount; if ( state == RemoveKnownFiles ) { //qDebug("state RemoveKnownFiles"); const QList<DocLnk> &list = dls.children(); for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { reference.remove( (*it)->file() ); // ### does this need to be deleted? } dit = new QDictIterator<void>(reference); state = MakeUnknownFiles; iterationI = 0; iterationCount = dit->count(); } if ( state == MakeUnknownFiles ) { //qDebug("state MakeUnknownFiles"); for (void* c; (c=dit->current()); ++(*dit) ) { if ( c == MAGIC_NUMBER ) { DocLnk* dl = new DocLnk; QFileInfo fi( dit->currentKey() ); dl->setFile( fi.filePath() ); dl->setName( fi.baseName() ); if ( store(dl) ) { ++*dit; iterationI++; if ( serverGui ) serverGui->documentScanningProgress( 75 + (25*iterationI)/iterationCount ); return dl; } } iterationI++; } delete dit; dit = 0; state = Done; } //qDebug("state Done"); return NULL; } #include "documentlist.moc" diff --git a/core/launcher/main.cpp b/core/launcher/main.cpp index 988e432..bf06e75 100644 --- a/core/launcher/main.cpp +++ b/core/launcher/main.cpp @@ -1,356 +1,357 @@ /********************************************************************** ** 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. ** **********************************************************************/ #ifndef QTOPIA_INTERNAL_FILEOPERATIONS #define QTOPIA_INTERNAL_FILEOPERATIONS #endif #include "server.h" #include "serverapp.h" #include "taskbar.h" #include "stabmon.h" #include "launcher.h" #include "firstuse.h" -#include "launcherglobal.h" + +#include <opie2/oglobal.h> #include <qtopia/qpeapplication.h> #include <qtopia/network.h> #include <qtopia/config.h> //#include <qtopia/custom.h> -#include <qtopia/global.h> + #include <qfile.h> #include <qdir.h> #ifdef QWS #include <qwindowsystem_qws.h> #include <qtopia/qcopenvelope_qws.h> #endif #include <qtopia/alarmserver.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #ifndef Q_OS_WIN32 #include <unistd.h> #else #include <process.h> #endif #include "calibrate.h" #ifdef QT_QWS_LOGIN #include "../login/qdmdialogimpl.h" #endif #ifdef Q_WS_QWS #include <qkeyboard_qws.h> #endif #include <qmessagebox.h> -#include <opie/odevice.h> +#include <opie2/odevice.h> using namespace Opie; static void cleanup() { - QDir dir( Opie::Global::tempDir(), "qcop-msg-*" ); + QDir dir( OGlobal::tempDirPath(), "qcop-msg-*" ); QStringList stale = dir.entryList(); QStringList::Iterator it; for ( it = stale.begin(); it != stale.end(); ++it ) { dir.remove( *it ); } } static void refreshTimeZoneConfig() { /* ### FIXME timezone handling */ #if 0 // We need to help WorldTime in setting up its configuration for // the current translation // BEGIN no tr const char *defaultTz[] = { "America/New_York", "America/Los_Angeles", "Europe/Oslo", "Asia/Tokyo", "Asia/Hong_Kong", "Australia/Brisbane", 0 }; // END no tr TimeZone curZone; QString zoneID; int zoneIndex; Config cfg = Config( "WorldTime" ); cfg.setGroup( "TimeZones" ); if (!cfg.hasKey( "Zone0" )){ // We have no existing timezones use the defaults which are untranslated strings QString currTz = TimeZone::current().id(); QStringList zoneDefaults; zoneDefaults.append( currTz ); for ( int i = 0; defaultTz[i] && zoneDefaults.count() < 6; i++ ) { if ( defaultTz[i] != currTz ) zoneDefaults.append( defaultTz[i] ); } zoneIndex = 0; for (QStringList::Iterator it = zoneDefaults.begin(); it != zoneDefaults.end() ; ++it){ cfg.writeEntry( "Zone" + QString::number( zoneIndex ) , *it); zoneIndex++; } } // We have an existing list of timezones refresh the // translations of TimeZone name zoneIndex = 0; while (cfg.hasKey( "Zone"+ QString::number( zoneIndex ))){ zoneID = cfg.readEntry( "Zone" + QString::number( zoneIndex )); curZone = TimeZone( zoneID ); if ( !curZone.isValid() ){ qDebug( "initEnvironment() Invalid TimeZone %s", zoneID.latin1() ); break; } cfg.writeEntry( "ZoneName" + QString::number( zoneIndex ), curZone.city() ); zoneIndex++; } #endif } void initEnvironment() { #ifdef Q_OS_WIN32 // Config file requires HOME dir which uses QDir which needs the winver qt_init_winver(); #endif Config config("locale"); config.setGroup( "Location" ); QString tz = config.readEntry( "Timezone", getenv("TZ") ).stripWhiteSpace(); // if not timezone set, pick New York if (tz.isNull() || tz.isEmpty()) tz = "America/New_York"; setenv( "TZ", tz, 1 ); config.writeEntry( "Timezone", tz); config.setGroup( "Language" ); QString lang = config.readEntry( "Language", getenv("LANG") ).stripWhiteSpace(); if( lang.isNull() || lang.isEmpty()) lang = "en_US"; setenv( "LANG", lang, 1 ); config.writeEntry("Language", lang); config.write(); #if 0 setenv( "QWS_SIZE", "240x320", 0 ); #endif QString env(getenv("QWS_DISPLAY")); if (env.contains("Transformed")) { int rot; // transformed driver default rotation is controlled by the hardware. Config config("qpe"); config.setGroup( "Rotation" ); if ( ( rot = config.readNumEntry( "Rot", -1 ) ) == -1 ) rot = ODevice::inst ( )-> rotation ( ) * 90; setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1); QPEApplication::defaultRotation ( ); /* to ensure deforient matches reality */ } } static void initKeyboard() { Config config("qpe"); config.setGroup( "Keyboard" ); int ard = config.readNumEntry( "RepeatDelay" ); int arp = config.readNumEntry( "RepeatPeriod" ); if ( ard > 0 && arp > 0 ) qwsSetKeyboardAutoRepeat( ard, arp ); QString layout = config.readEntry( "Layout", "us101" ); Server::setKeyboardLayout( layout ); } static bool firstUse() { bool needFirstUse = FALSE; if ( QWSServer::mouseHandler() && QWSServer::mouseHandler() ->inherits("QCalibratedMouseHandler") ) { if ( !QFile::exists( "/etc/pointercal" ) ) needFirstUse = TRUE; } { Config config( "qpe" ); config.setGroup( "Startup" ); needFirstUse |= config.readBoolEntry( "FirstUse", TRUE ); } if ( !needFirstUse ) return FALSE; FirstUse *fu = new FirstUse(); fu->exec(); bool rs = fu->restartNeeded(); delete fu; return rs; } int initApplication( int argc, char ** argv ) { cleanup(); initEnvironment(); //Don't flicker at startup: #ifdef QWS QWSServer::setDesktopBackground( QImage() ); #endif ServerApplication a( argc, argv, QApplication::GuiServer ); refreshTimeZoneConfig(); initKeyboard(); // Don't use first use under Windows if ( firstUse() ) { a.restart(); return 0; } ODevice::inst ( )-> setSoftSuspend ( true ); { QCopEnvelope e("QPE/System", "setBacklight(int)" ); e << -3; // Forced on } AlarmServer::initialize(); Server *s = new Server(); (void)new SysFileMonitor(s); #ifdef QWS Network::createServer(s); #endif s->show(); /* THE ARM rtc has problem holdings the time on reset */ if ( QDate::currentDate ( ). year ( ) < 2000 ) { if ( QMessageBox::information ( 0, ServerApplication::tr( "Information" ), ServerApplication::tr( "<p>The system date doesn't seem to be valid.\n(%1)</p><p>Do you want to correct the clock ?</p>" ). arg( TimeString::dateString ( QDate::currentDate ( ))), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) { QCopEnvelope e ( "QPE/Application/systemtime", "setDocument(QString)" ); e << QString ( ); } } int rv = a.exec(); qDebug("exiting..."); delete s; #ifndef Q_OS_MACX ODevice::inst()->setSoftSuspend( false ); #endif return rv; } static const char *pidfile_path = "/var/run/opie.pid"; void create_pidfile ( ) { FILE *f; if (( f = ::fopen ( pidfile_path, "w" ))) { ::fprintf ( f, "%d", getpid ( )); ::fclose ( f ); } } void remove_pidfile ( ) { ::unlink ( pidfile_path ); } void handle_sigterm ( int /* sig */ ) { if ( qApp ) qApp-> quit ( ); } #ifndef Q_OS_WIN32 int main( int argc, char ** argv ) { ::signal ( SIGCHLD, SIG_IGN ); ::signal ( SIGTERM, handle_sigterm ); ::signal ( SIGINT, handle_sigterm ); ::setsid ( ); ::setpgid ( 0, 0 ); ::atexit ( remove_pidfile ); create_pidfile ( ); int retVal = initApplication( argc, argv ); // Have we been asked to restart? if ( ServerApplication::doRestart ) { for ( int fd = 3; fd < 100; fd++ ) close( fd ); execl( (QPEApplication::qpeDir()+"bin/qpe").latin1(), "qpe", 0 ); } // Kill them. Kill them all. ::kill ( 0, SIGTERM ); ::sleep ( 1 ); ::kill ( 0, SIGKILL ); return retVal; } #else int main( int argc, char ** argv ) { int retVal = initApplication( argc, argv ); if ( DesktopApplication::doRestart ) { qDebug("Trying to restart"); execl( (QPEApplication::qpeDir()+"bin\\qpe").latin1(), "qpe", 0 ); } return retVal; } #endif diff --git a/core/launcher/qcopbridge.cpp b/core/launcher/qcopbridge.cpp index 9cb56ce..b45f0cc 100644 --- a/core/launcher/qcopbridge.cpp +++ b/core/launcher/qcopbridge.cpp @@ -1,497 +1,498 @@ /********************************************************************** ** 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 "qcopbridge.h" #include "transferserver.h" +#include <opie2/oglobal.h> + #ifdef Q_WS_QWS #include <qtopia/qcopenvelope_qws.h> #endif #include <qtopia/qpeapplication.h> -#include <qtopia/global.h> + #include <qtopia/version.h> #include <qtopia/config.h> #include <qdir.h> #include <qfile.h> #include <qtextstream.h> #include <qdatastream.h> #include <qcstring.h> #include <qstringlist.h> #include <qfileinfo.h> #include <qregexp.h> #include <qtimer.h> #ifdef Q_WS_QWS #include <qcopchannel_qws.h> #endif #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #ifndef Q_OS_WIN32 #include <pwd.h> #include <unistd.h> #include <sys/types.h> #endif #if defined(_OS_LINUX_) #include <shadow.h> #endif -#include "launcherglobal.h" //#define INSECURE const int block_size = 51200; QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent, const char* name ) : QServerSocket( port, 1, parent, name ), desktopChannel( 0 ), cardChannel( 0 ) { if ( !ok() ) qWarning( "Failed to bind to port %d", port ); else { #ifndef QT_NO_COP desktopChannel = new QCopChannel( "QPE/Desktop", this ); connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); cardChannel = new QCopChannel( "QPE/Card", this ); connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); #endif } sendSync = FALSE; openConnections.setAutoDelete( TRUE ); authorizeConnections(); } QCopBridge::~QCopBridge() { #ifndef QT_NO_COP delete desktopChannel; #endif } void QCopBridge::authorizeConnections() { Config cfg("Security"); cfg.setGroup("SyncMode"); m_mode = Mode(cfg.readNumEntry("Mode", Sharp )); QListIterator<QCopBridgePI> it(openConnections); while ( it.current() ) { if ( !it.current()->verifyAuthorised() ) { disconnect ( it.current(), SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( closed( QCopBridgePI *) ) ); openConnections.removeRef( it.current() ); } else ++it; } } void QCopBridge::newConnection( int socket ) { QCopBridgePI *pi = new QCopBridgePI( socket, this ); openConnections.append( pi ); connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( closed( QCopBridgePI *) ) ); /* ### libqtopia merge FIXME */ #if 0 QPEApplication::setTempScreenSaverMode( QPEApplication::DisableSuspend ); #endif #ifndef QT_NO_COP QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend; #endif if ( sendSync ) { pi ->startSync(); sendSync = FALSE; } } void QCopBridge::closed( QCopBridgePI *pi ) { emit connectionClosed( pi->peerAddress() ); openConnections.removeRef( pi ); if ( openConnections.count() == 0 ) { /* ### FIXME libqtopia merge */ #if 0 QPEApplication::setTempScreenSaverMode( QPEApplication::Enable ); #endif #ifndef QT_NO_COP QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; #endif } } void QCopBridge::closeOpenConnections() { QCopBridgePI *pi; for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) pi->close(); } void QCopBridge::desktopMessage( const QCString &command, const QByteArray &data ) { if ( command == "startSync()" ) { // we need to buffer it a bit sendSync = TRUE; startTimer( 20000 ); } if ( m_mode & Qtopia1_7 ) { // send the command to all open connections QCopBridgePI *pi; for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) { pi->sendDesktopMessage( command, data ); } } if ( m_mode & Sharp ) sendDesktopMessageOld( command, data ); } #ifndef OPIE_NO_OLD_SYNC_CODE /* * Old compat mode */ void QCopBridge::sendDesktopMessageOld( const QCString& command, const QByteArray& args) { command.stripWhiteSpace(); int paren = command.find( "(" ); if ( paren <= 0 ) { qDebug("DesktopMessage: bad qcop syntax"); return; } QString params = command.mid( paren + 1 ); if ( params[params.length()-1] != ')' ) { qDebug("DesktopMessage: bad qcop syntax"); return; } params.truncate( params.length()-1 ); QStringList paramList = QStringList::split( ",", params ); QString data; if ( paramList.count() ) { QDataStream stream( args, IO_ReadOnly ); for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { QString str; if ( *it == "QString" ) { stream >> str; } else if ( *it == "QCString" ) { QCString cstr; stream >> cstr; str = QString::fromLocal8Bit( cstr ); } else if ( *it == "int" ) { int i; stream >> i; str = QString::number( i ); } else if ( *it == "bool" ) { int i; stream >> i; str = QString::number( i ); } else { qDebug(" cannot route the argument type %s throught the qcop bridge", (*it).latin1() ); return; } QString estr; for (int i=0; i<(int)str.length(); i++) { QChar ch = str[i]; if ( ch.row() ) goto quick; switch (ch.cell()) { case '&': estr.append( "&" ); break; case ' ': estr.append( "&0x20;" ); break; case '\n': estr.append( "&0x0d;" ); break; case '\r': estr.append( "&0x0a;" ); break; default: quick: estr.append(ch); } } data += " " + estr; } } QString sendCommand = QString(command.data()) + data; // send the command to all open connections QCopBridgePI *pi; for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) pi->sendDesktopMessage( sendCommand ); } #endif void QCopBridge::timerEvent( QTimerEvent * ) { sendSync = FALSE; killTimers(); } QCopBridgePI::QCopBridgePI( int socket, QObject *parent, const char* name ) : QSocket( parent, name ) { setSocket( socket ); peerport = peerPort(); peeraddress = peerAddress(); #ifndef INSECURE if ( !SyncAuthentication::isAuthorized(peeraddress) ) { state = Forbidden; close(); } else #endif { state = Connected; connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); QString intro="220 Qtopia "; intro += QPE_VERSION; intro += ";"; intro += "challenge="; intro += SyncAuthentication::serverId(); intro += ";"; // No tr intro += "loginname="; intro += SyncAuthentication::loginName(); intro += ";"; intro += "displayname="; intro += SyncAuthentication::ownerName(); intro += ";"; send( intro ); state = Wait_USER; } sendSync = FALSE; connect( this, SIGNAL( connectionClosed() ), SLOT( myConnectionClosed() ) ); // idle timer to close connections when not used anymore timer = new QTimer(this); connect( timer, SIGNAL(timeout()), this, SLOT(myConnectionClosed()) ); timer->start( 300000, TRUE ); } QCopBridgePI::~QCopBridgePI() { } bool QCopBridgePI::verifyAuthorised() { if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { state = Forbidden; return FALSE; } return TRUE; } void QCopBridgePI::myConnectionClosed() { emit connectionClosed( this ); } void QCopBridgePI::sendDesktopMessage( const QString &msg ) { QString str = "CALL QPE/Desktop " + msg; // No tr send ( str ); } void QCopBridgePI::sendDesktopMessage( const QCString &msg, const QByteArray& data ) { if ( !isOpen() ) // eg. Forbidden return; const char hdr[]="CALLB QPE/Desktop "; writeBlock(hdr,sizeof(hdr)-1); writeBlock(msg,msg.length()); writeBlock(" ",1); - QByteArray b64 = Opie::Global::encodeBase64(data); + QByteArray b64 = OGlobal::encodeBase64(data); writeBlock(b64.data(),b64.size()); writeBlock("\r\n",2); } void QCopBridgePI::send( const QString& msg ) { if ( !isOpen() ) // eg. Forbidden return; QTextStream os( this ); os << msg << endl; //qDebug( "sending qcop message: %s", msg.latin1() ); } void QCopBridgePI::read() { while ( canReadLine() ) { timer->start( 300000, TRUE ); process( readLine().stripWhiteSpace() ); } } void QCopBridgePI::process( const QString& message ) { //qDebug( "Command: %s", message.latin1() ); // 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]; // we always respond to QUIT, regardless of state if ( cmd == "QUIT" ) { send( "211 Have a nice day!" ); // No tr close(); return; } // connected to client if ( Connected == state ) 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; } // 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; if ( sendSync ) { sendDesktopMessage( "startSync()" ); sendSync = FALSE; } return; } // noop (NOOP) else if ( cmd == "NOOP" ) { send( "200 Command okay" ); // No tr } // call (CALL) else if ( cmd == "CALL" ) { // example: call QPE/System execute(QString) addressbook if ( msg.count() < 3 ) { send( "500 Syntax error, command unrecognized" ); // No tr } else { QString channel = msg[1]; QString command = msg[2]; command.stripWhiteSpace(); int paren = command.find( "(" ); if ( paren <= 0 ) { send( "500 Syntax error, command unrecognized" ); // No tr return; } QString params = command.mid( paren + 1 ); if ( params[(int)params.length()-1] != ')' ) { send( "500 Syntax error, command unrecognized" ); // No tr return; } params.truncate( params.length()-1 ); QByteArray buffer; QDataStream ds( buffer, IO_WriteOnly ); int msgId = 3; QStringList paramList = QStringList::split( ",", params ); if ( paramList.count() > msg.count() - 3 ) { send( "500 Syntax error, command unrecognized" ); // No tr return; } for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { QString arg = msg[msgId]; arg.replace( QRegExp("&0x20;"), " " ); arg.replace( QRegExp("&"), "&" ); arg.replace( QRegExp("&0x0d;"), "\n" ); arg.replace( QRegExp("&0x0a;"), "\r" ); if ( *it == "QString" ) ds << arg; else if ( *it == "QCString" ) ds << arg.local8Bit(); else if ( *it == "int" ) ds << arg.toInt(); else if ( *it == "bool" ) ds << arg.toInt(); else { send( "500 Syntax error, command unrecognized" ); // No tr return; } msgId++; } #ifndef QT_NO_COP if ( !QCopChannel::isRegistered( channel.latin1() ) ) { // send message back about it QString answer = "599 ChannelNotRegistered " + channel; send( answer ); return; } #endif #ifndef QT_NO_COP if ( paramList.count() ) QCopChannel::send( channel.latin1(), command.latin1(), buffer ); else QCopChannel::send( channel.latin1(), command.latin1() ); send( "200 Command okay" ); // No tr #endif } } // not implemented else send( "502 Command not implemented" ); // No tr } diff --git a/core/launcher/screensaver.cpp b/core/launcher/screensaver.cpp index 48770e8..1146dcd 100644 --- a/core/launcher/screensaver.cpp +++ b/core/launcher/screensaver.cpp @@ -1,329 +1,329 @@ #include "screensaver.h" #include <qpe/config.h> #include <qpe/power.h> #include <qpe/network.h> -#include <opie/odevice.h> +#include <opie2/odevice.h> using namespace Opie; OpieScreenSaver::OpieScreenSaver ( ) : QObject ( 0, "screensaver" ), QWSScreenSaver ( ) { 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_use_light_sensor = false; m_backlight_sensor = -1; ::memset ( m_sensordata, 0xff, LS_Count * sizeof( m_sensordata [0] )); m_lcd_status = true; m_backlight_normal = -1; m_backlight_current = -1; m_backlight_forcedoff = false; m_on_ac = false; 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 ); } /** * Stops the screen saver */ void OpieScreenSaver::restore() { m_level = -1; if ( !m_lcd_status ) { // We must have turned it off ODevice::inst ( ) -> setDisplayStatus ( true ); m_lcd_status = true; } 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; } /** * 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 ); } //qDebug("screen saver intervals: %d %d %d", dim, lightoff, suspend); 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 ); } void OpieScreenSaver::setMode ( int 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); } /** * 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; } } /** * 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 ( ); 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 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] ); 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; } } /** * 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 ( ); } } diff --git a/core/launcher/server.cpp b/core/launcher/server.cpp index b9580c7..32fcdd0 100644 --- a/core/launcher/server.cpp +++ b/core/launcher/server.cpp @@ -1,730 +1,730 @@ /********************************************************************** ** 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 "launcher.h" #include "startmenu.h" #include "transferserver.h" #include "qcopbridge.h" #include "irserver.h" #include "packageslave.h" #include "calibrate.h" #include "qrsync.h" #include "syncdialog.h" #include "launcher.h" #include "shutdownimpl.h" #include "applauncher.h" #if 0 #include "suspendmonitor.h" #endif #include "documentlist.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 <qwindowsystem_qws.h> #include <qgfx_qws.h> #include <qtopia/global.h> //#include <qtopia/custom.h> -#include <opie/odevicebutton.h> -#include <opie/odevice.h> +#include <opie2/odevicebutton.h> +#include <opie2/odevice.h> #include <unistd.h> #include <qmainwindow.h> #include <qmessagebox.h> #include <qtimer.h> #include <qtextstream.h> #include <stdlib.h> extern QRect qt_maxWindowRect; using namespace Opie; 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; \ } #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 #endif #if !defined(OPIE_NO_BUILTIN_SHUTDOWN) { "shutdown", Global::shutdown, 1, 0 }, // No tr // { "run", run, 1, 0 }, // No tr #endif { 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::ODeviceButton*,bool)), this,SLOT(activate(const Opie::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 &)) ); QCopChannel *tbChannel = new QCopChannel( "QPE/TaskBar", this ); connect( tbChannel, SIGNAL(received(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 QT_VERSION < 0x030000 QRect mwr = qt_screen->mapToDevice(qt_maxWindowRect, QSize(qt_screen->width(),qt_screen->height()) ); # else QRect mwr = qt_maxWindowRect; # endif if ( mwr.contains(w->requested().boundingRect()) ) return TRUE; } } } #endif return FALSE; } void Server::activate(const Opie::ODeviceButton* button, bool held) { Global::terminateBuiltin("calibrate"); // No tr Opie::OQCopMessage om; if ( held ) { om = button->heldAction(); } else { 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(); } #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; } 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++; } } 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(); } /* ### FIXME support TempScreenSaverMode */ #if 0 else if ( msg == "setTempScreenSaverMode(int,int)" ) { int mode, pid; stream >> mode >> pid; tsmMonitor->setTempMode(mode, pid); } #endif else if ( msg == "linkChanged(QString)" ) { QString link; stream >> link; qDebug( "desktop.cpp systemMsg -> linkchanged( %s )", link.latin1() ); docList->linkChanged(link); } else if ( msg == "serviceChanged(QString)" ) { MimeType::updateApplications(); } else if ( msg == "mkdir(QString)" ) { 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 ); } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) { 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 ); #ifndef QT_NO_COP 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 ); } else if ( msg == "sendHandshakeInfo()" ) { QString home = getenv( "HOME" ); #ifndef QT_NO_COP 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)" ); /* ### FIXME Architecture ### */ e << QString::fromLatin1("1.7") << "Uncustomized Device"; } else if ( msg == "sendCardInfo()" ) { #ifndef QT_NO_COP 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; #ifndef QT_NO_COP e << s; #endif } else if ( msg == "sendSyncDate(QString)" ) { 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 ); #endif //qDebug("QPE/System sendSyncDate for %s: response %s", app.latin1(), //cfg.readEntry( app ).latin1() ); } else if ( msg == "setSyncDate(QString,QString)" ) { QString app, date; stream >> app >> date; Config cfg( "qpe" ); cfg.setGroup("SyncDate"); cfg.writeEntry( app, date ); //qDebug("setSyncDate(QString,QString) %s %s", app.latin1(), date.latin1()); } else if ( msg == "startSync(QString)" ) { 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; } else if (msg == "restoreDone(QString)") { docList->restoreDone(); } else if ( msg == "getAllDocLinks()" ) { docList->sendAllDocLinks(); } #ifdef Q_WS_QWS else if ( msg == "setMouseProto(QString)" ) { 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(); } 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 ); } else if ( msg == "setKeyboardLayout(QString)" ) { 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(); } else if ( msg == "soundAlarm()" ) { ServerApplication::soundAlarm(); } else if ( msg == "setLed(int,bool)" ) { int led, status; stream >> led >> status; QValueList <OLed> ll = ODevice::inst ( )-> ledList ( ); 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; // 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) { //qDebug("No seperators found in path %s", localPath.latin1()); 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()) { //qDebug("mkdir making dir %s", checkedPath.latin1()); if (!checkDir.mkdir(checkedPath)) { qDebug("Unable to make directory %s", checkedPath.latin1()); 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; } } if ( !transferServer ) { // start transfer server transferServer = new TransferServer( 4242 ); if ( transferServer->ok() ) { // ... OK } else { delete transferServer; transferServer = 0; } } if ( !transferServer || !qcopBridge ) tid_xfer = startTimer( 2000 ); } void Server::timerEvent( QTimerEvent *e ) { if ( e->timerId() == tid_xfer ) { 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"); #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()"); } } } #endif } void Server::terminateServers() { delete transferServer; delete qcopBridge; transferServer = 0; qcopBridge = 0; } void Server::syncConnectionClosed( const QHostAddress & ) { qDebug( "Lost sync connection" ); 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; } #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( "qtopia-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()"); #endif } } diff --git a/core/launcher/server.pro b/core/launcher/server.pro index 0513536..f82c741 100644 --- a/core/launcher/server.pro +++ b/core/launcher/server.pro @@ -1,125 +1,124 @@ TEMPLATE = app CONFIG += qtopia warn_on release DESTDIR = $$(OPIEDIR)/bin HEADERS += server.h \ serverinterface.h \ launchertab.h \ documentlist.h \ appicons.h \ taskbar.h \ runningappbar.h \ applauncher.h \ stabmon.h \ inputmethods.h \ systray.h \ wait.h \ shutdownimpl.h \ launcher.h \ launcherview.h \ $$(OPIEDIR)/core/apps/calibrate/calibrate.h \ startmenu.h \ transferserver.h \ qcopbridge.h \ packageslave.h \ irserver.h \ firstuse.h \ $$(OPIEDIR)/rsync/buf.h \ $$(OPIEDIR)/rsync/checksum.h \ $$(OPIEDIR)/rsync/command.h \ $$(OPIEDIR)/rsync/emit.h \ $$(OPIEDIR)/rsync/job.h \ $$(OPIEDIR)/rsync/netint.h \ $$(OPIEDIR)/rsync/protocol.h \ $$(OPIEDIR)/rsync/prototab.h \ $$(OPIEDIR)/rsync/rsync.h \ $$(OPIEDIR)/rsync/search.h \ $$(OPIEDIR)/rsync/stream.h \ $$(OPIEDIR)/rsync/sumset.h \ $$(OPIEDIR)/rsync/trace.h \ $$(OPIEDIR)/rsync/types.h \ $$(OPIEDIR)/rsync/util.h \ $$(OPIEDIR)/rsync/whole.h \ $$(OPIEDIR)/rsync/config_rsync.h \ $$(OPIEDIR)/rsync/qrsync.h \ syncdialog.h \ serverapp.h \ - launcherglobal.h \ qprocess.h \ screensaver.h SOURCES += server.cpp \ serverinterface.cpp \ launchertab.cpp \ documentlist.cpp \ appicons.cpp \ taskbar.cpp \ runningappbar.cpp \ applauncher.cpp \ stabmon.cpp \ inputmethods.cpp \ systray.cpp \ wait.cpp \ shutdownimpl.cpp \ launcher.cpp \ launcherview.cpp \ $$(OPIEDIR)/core/apps/calibrate/calibrate.cpp \ transferserver.cpp \ packageslave.cpp \ irserver.cpp \ qcopbridge.cpp \ startmenu.cpp \ main.cpp \ firstuse.cpp \ $$(OPIEDIR)/rsync/base64.c \ $$(OPIEDIR)/rsync/buf.c \ $$(OPIEDIR)/rsync/checksum.c \ $$(OPIEDIR)/rsync/command.c \ $$(OPIEDIR)/rsync/delta.c \ $$(OPIEDIR)/rsync/emit.c \ $$(OPIEDIR)/rsync/hex.c \ $$(OPIEDIR)/rsync/job.c \ $$(OPIEDIR)/rsync/mdfour.c \ $$(OPIEDIR)/rsync/mksum.c \ $$(OPIEDIR)/rsync/msg.c \ $$(OPIEDIR)/rsync/netint.c \ $$(OPIEDIR)/rsync/patch.c \ $$(OPIEDIR)/rsync/prototab.c \ $$(OPIEDIR)/rsync/readsums.c \ $$(OPIEDIR)/rsync/scoop.c \ $$(OPIEDIR)/rsync/search.c \ $$(OPIEDIR)/rsync/stats.c \ $$(OPIEDIR)/rsync/stream.c \ $$(OPIEDIR)/rsync/sumset.c \ $$(OPIEDIR)/rsync/trace.c \ $$(OPIEDIR)/rsync/tube.c \ $$(OPIEDIR)/rsync/util.c \ $$(OPIEDIR)/rsync/version.c \ $$(OPIEDIR)/rsync/whole.c \ $$(OPIEDIR)/rsync/qrsync.cpp \ syncdialog.cpp \ serverapp.cpp \ - launcherglobal.cpp \ qprocess.cpp \ qprocess_unix.cpp \ screensaver.cpp INCLUDEPATH += $(OPIEDIR)/core/apps/calibrate DEPENDPATH += $(OPIEDIR)/core/apps/calibrate INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/rsync DEPENDPATH += $(OPIEDIR)/rsync TARGET = qpe +#needs OWait and ODevice CONFTEST = $$system( echo $CONFIG_TARGET_MACOSX ) contains( CONFTEST, y ){ - LIBS += -lqpe -lopie + LIBS += -lqpe -lopiecore2 -lopieui2 }else{ - LIBS += -lcrypt -lqpe -lopie + LIBS += -lcrypt -lqpe -lopiecore2 -lopieui2 } include ( $(OPIEDIR)/include.pro ) diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp index b84eed8..c199063 100644 --- a/core/launcher/startmenu.cpp +++ b/core/launcher/startmenu.cpp @@ -1,394 +1,394 @@ /**********************************************************************
** 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.
**
**********************************************************************/
// TODO. During startup
// Launcher::typeAdded
// is called for each new tab and calls then each time the refresh of startmenu
// suboptimal
#define INCLUDE_MENUITEM_DEF
#include "startmenu.h"
#include <qtopia/qpeapplication.h>
#include <qtopia/config.h>
#include <qtopia/applnk.h>
#include <qtopia/global.h>
#include <qtopia/resource.h>
#include <qtopia/mimetype.h>
#include <qtopia/qlibrary.h>
#include <qdict.h>
#include <qdir.h>
//#include <qpainter.h>
//#include <stdlib.h>
#define APPLNK_ID_OFFSET 250
#define NO_ID -1
void StartPopupMenu::keyPressEvent( QKeyEvent *e )
{
if ( e->key() == Key_F33 || e->key() == Key_Space ) {
// "OK" button, little hacky
QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0);
QPopupMenu::keyPressEvent( &ke );
} else {
QPopupMenu::keyPressEvent( e );
}
}
//---------------------------------------------------------------------------
StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
{
startButtonPixmap = "go"; // No tr
int sz = AppLnk::smallIconSize()+3;
QPixmap pm;
pm.convertFromImage(Resource::loadImage( startButtonPixmap).smoothScale( sz,sz) );
setPixmap(pm);
setFocusPolicy( NoFocus );
useWidePopupMenu = true;
launchMenu = 0;
refreshMenu();
}
void StartMenu::mousePressEvent( QMouseEvent * )
{
launch();
}
StartMenu::~StartMenu()
{
clearApplets();
}
void StartMenu::createMenu()
{
clearApplets();
delete launchMenu;
launchMenu = new StartPopupMenu( this );
loadMenu( launchMenu );
loadApplets();
bool result = currentItem || menuApplets.count();
if ( result )
connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
}
void StartMenu::refreshMenu()
{
Config cfg( "StartMenu" );
cfg.setGroup( "Menu" );
bool ltabs = cfg.readBoolEntry( "LauncherTabs", TRUE );
bool lot = cfg.readBoolEntry( "LauncherOther", TRUE );
useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
if ( launchMenu && !(ltabs || lot) ) return; // nothing to do
createMenu();
}
void StartMenu::itemSelected( int id )
{
if ( id == NO_ID ) return;
if ( id < 0 ) {
MenuApplet *applet = menuApplets.find( id );
if ( applet ) {
applet->iface->activated();
}
} else if ( id >= APPLNK_ID_OFFSET ) {
AppLnk * appLnk = appLnks.find( id );
if ( appLnk ) {
appLnk->execute();
}
} else {
QString *tabName = tabNames.find( id );
if ( tabName ) {
emit tabSelected( *tabName );
}
}
}
void StartMenu::createAppEntry( QPopupMenu *menu, QDir dir, QString file )
{
if ( file.right(8) == ".desktop" ) {
AppLnk* applnk = new AppLnk( dir.path() + "/" + file );
if ( !applnk->isValid() ) {
delete applnk;
return;
}
if ( applnk->type() == "Separator" ) { // No tr
menu->insertSeparator();
delete applnk;
} else {
QPixmap test;
QImage img = Resource::loadImage( applnk->icon() );
if(!img.isNull() )
test.convertFromImage(
img.smoothScale(
AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 );
menu->insertItem( test, applnk->name(),
currentItem + APPLNK_ID_OFFSET );
appLnks.insert( currentItem + APPLNK_ID_OFFSET, applnk );
currentItem++;
}
}
}
void StartMenu::createDirEntry( QPopupMenu *menu, QDir dir, QString file, bool lot )
{
// do some sanity checks and collect information
if ( file == "." || file == ".." ) return;
Config cfg( dir.path() + "/" + file + "/.directory", Config::File );
if ( !cfg.isValid() ) return;
QString name = cfg.readEntry( "Name" );
QString icon = cfg.readEntry( "Icon" );
if ( !name || !icon ) return;
QDir subdir = QDir( dir );
subdir.cd( file );
subdir.setFilter( QDir::Files );
subdir.setNameFilter( "*.desktop" );
// we don' t show the menu if there are no entries
// perhaps one should check if there exist subsubdirs with entries...
if ( subdir.entryList().isEmpty() ) return;
// checks were ok
QPixmap test;
test.convertFromImage( Resource::loadImage( icon ).smoothScale(
AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 );
if ( useWidePopupMenu ) {
// generate submenu
QPopupMenu *submenu = new QPopupMenu( menu );
connect( submenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
menu->insertItem( test, name, submenu, NO_ID );
// ltabs is true cause else we wouldn't stuck around..
createMenuEntries( submenu, subdir, true, lot );
} else {
// no submenus - just bring corresponding tab to front
menu->insertItem( test, name, currentItem );
tabNames.insert( currentItem, new QString( file ) );
currentItem++;
}
}
void StartMenu::createMenuEntries( QPopupMenu *menu, QDir dir, bool ltabs, bool lot )
{
if ( lot ) {
dir.setFilter( QDir::Files );
dir.setNameFilter( "*.desktop" );
QStringList files = dir.entryList();
files.sort();
for ( QStringList::Iterator it = files.begin(); it != files.end(); it++ ) {
createAppEntry( menu, dir, *it );
}
}
if ( ltabs ) {
dir.setNameFilter( "*" );
dir.setFilter( QDir::Dirs );
QStringList dirs = dir.entryList();
dirs.sort();
for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); it++ ) {
createDirEntry( menu, dir, *it, lot );
}
}
}
bool StartMenu::loadMenu( QPopupMenu *menu )
{
Config cfg("StartMenu");
cfg.setGroup("Menu");
bool ltabs = cfg.readBoolEntry("LauncherTabs", TRUE);
bool lot = cfg.readBoolEntry("LauncherOther", TRUE);
useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
bool sepfirst = !ltabs && !lot;
currentItem = 0;
launchMenu->clear();
appLnks.setAutoDelete( true );
tabNames.setAutoDelete( true );
appLnks.clear();
tabNames.clear();
appLnks.setAutoDelete( false );
tabNames.setAutoDelete( false );
QDir dir( MimeType::appsFolderName(), QString::null, QDir::Name );
createMenuEntries( menu, dir, ltabs, lot );
if ( !menu->count() ) sepfirst = TRUE;
launchMenu->setName( sepfirst ? "accessories" : "accessories_need_sep" ); // No tr
return currentItem;
}
void StartMenu::launch()
{
int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
if ( launchMenu->isVisible() )
launchMenu->hide();
else
launchMenu->popup( QPoint( 1, y ) );
}
static int compareAppletPositions(const void *b, const void *a)
{
const MenuApplet* aa = *(const MenuApplet**)a;
const MenuApplet* ab = *(const MenuApplet**)b;
int d = aa->iface->position() - ab->iface->position();
if ( d ) return d;
return QString::compare(aa->library->library(),ab->library->library());
}
void StartMenu::clearApplets()
{
if ( launchMenu )
launchMenu-> hide();
for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) {
MenuApplet *applet = it.current();
if ( launchMenu ) {
launchMenu->removeItem( applet-> id );
delete applet->popup;
}
applet->iface->release();
applet->library->unload();
delete applet-> library;
}
menuApplets.clear();
}
void StartMenu::loadApplets()
{
Config cfg( "StartMenu" );
cfg.setGroup( "Applets" );
// SafeMode causes too much problems, so we disable it for now --
// maybe we should reenable it for OPIE 1.0 - sandman 26.09.02
// removed in the remerge PluginManager could handle it
// we don't currently use it -zecke
QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' );
QString lang = getenv( "LANG" );
QString path = QPEApplication::qpeDir() + "/plugins/applets";
QDir dir( path, "lib*.so" );
QStringList list = dir.entryList();
QStringList::Iterator it;
int napplets = 0;
MenuApplet* *xapplets = new MenuApplet*[list.count()];
for ( it = list.begin(); it != list.end(); ++it ) {
if ( exclude.find( *it ) != exclude.end() )
continue;
MenuAppletInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if (( lib->queryInterface( IID_MenuApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) {
MenuApplet *applet = new MenuApplet;
xapplets[napplets++] = applet;
applet->library = lib;
applet->iface = iface;
QTranslator *trans = new QTranslator(qApp);
QString type = (*it).left( (*it).find(".") );
QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
if ( trans->load( tfn ))
qApp->installTranslator( trans );
else
delete trans;
} else {
exclude += *it;
delete lib;
}
}
cfg.writeEntry( "ExcludeApplets", exclude, ',' );
qsort(xapplets, napplets, sizeof(menuApplets[0]), compareAppletPositions);
while ( napplets-- ) {
MenuApplet *applet = xapplets[napplets];
-
applet->popup = applet->iface->popup( this );
// menuApplets got an id < -1
menuApplets.insert( -( currentItem + 2 ), new MenuApplet( *applet ) );
currentItem++;
}
delete [] xapplets;
addApplets( launchMenu );
}
/*
* Launcher calls loadMenu too often fix that
*/
void StartMenu::addApplets(QPopupMenu* pop) {
QIntDict<MenuApplet> dict;
if( pop-> count ( ))
pop-> insertSeparator ( );
for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) {
MenuApplet *applet = it.current();
if ( applet->popup )
applet->id = pop->insertItem( applet->iface->icon(),
applet->iface->text(), applet->popup );
else
applet->id = pop->insertItem( applet->iface->icon(),
applet->iface->text() );
+
dict.insert( applet->id, new MenuApplet( *applet ) );
}
/* need to update the key */
menuApplets.setAutoDelete( true );
menuApplets.clear();
menuApplets.setAutoDelete( false );
menuApplets = dict;
}
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp index 9519d11..9cb9d7a 100644 --- a/core/launcher/transferserver.cpp +++ b/core/launcher/transferserver.cpp @@ -1,1256 +1,1255 @@ /********************************************************************** ** 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. ** **********************************************************************/ //#define _XOPEN_SOURCE -#include <qtopia/global.h> +#include <opie2/oglobal.h> #include <qtopia/qpeapplication.h> #ifndef Q_OS_WIN32 #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 */ +#endif /* Q_OS_MACX */ #else #include <stdlib.h> #include <time.h> #endif #if defined(_OS_LINUX_) #include <shadow.h> #endif #include <qdir.h> #include <qfile.h> #include <qtextstream.h> #include <qdatastream.h> #include <qmessagebox.h> #include <qstringlist.h> #include <qfileinfo.h> #include <qregexp.h> //#include <qtopia/qcopchannel_qws.h> #include <qtopia/process.h> #include <qtopia/global.h> #include <qtopia/config.h> #include <qtopia/private/contact.h> #include <qtopia/quuid.h> #include <qtopia/version.h> #ifdef Q_WS_QWS #include <qtopia/qcopenvelope_qws.h> #endif -#include "launcherglobal.h" #include "transferserver.h" #include <qtopia/qprocess.h> 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() ) qWarning( "Failed to bind to port %d", port ); } 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; } } 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 = Opie::Global::uuid(); + 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(); } 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; } 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 ); // Note: some systems use more than crypt for passwords. QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); if ( cpwd == cpassword ) return TRUE; #endif static int lastdenial=0; static int denials=0; int now = time(0); - + Config cfg("Security"); - cfg.setGroup("Sync"); + cfg.setGroup("Sync"); QString syncapp = cfg.readEntry("syncapp","Qtopia"); - + //No password needed if the user really wants it if (syncapp == "IntelliSync") { return TRUE; - } - + } + // Detect old Qtopia Desktop (no password) - if ( password.isEmpty() ) { + 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(); denials++; lastdenial=now; - } + } return FALSE; - - } + + } // Second, check sync password... static int lock=0; if ( lock ) return FALSE; - ++lock; + ++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) { #ifndef Q_OS_WIN32 QString cpassword = QString::fromLocal8Bit( crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); #else // ### 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)]; #ifndef Q_OS_WIN32 QString cpassword = QString::fromLocal8Bit( crypt( password.mid(8).local8Bit(), salt ) ); #else //### revise QString cpassword(""); #endif 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 ); } else #endif { connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); passiv = FALSE; for( int i = 0; i < 4; i++ ) wait[i] = FALSE; 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 ) ) ); directory = QDir::currentDirPath(); static int p = 1024; 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; } return TRUE; } void ServerPI::connectionClosed() { // qDebug( "Debug: Connection closed" ); emit connectionClosed(this); } void ServerPI::send( const QString& msg ) { QTextStream os( this ); os << msg << endl; //qDebug( "Reply: %s", msg.latin1() ); } void ServerPI::read() { while ( canReadLine() ) process( readLine().stripWhiteSpace() ); } bool ServerPI::checkReadFile( const QString& file ) { QString filename; if ( file[0] != "/" ) filename = directory.path() + "/" + file; else 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; else filename = file; QFileInfo fi( filename ); if ( fi.exists() ) if ( !QFile( filename ).remove() ) return FALSE; return TRUE; } void ServerPI::process( const QString& message ) { //qDebug( "Command: %s", message.latin1() ); // 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]; // 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( " " ); } //qDebug( "args: %s", args.latin1() ); // we always respond to QUIT, regardless of state if ( cmd == "QUIT" ) { send( "211 Good bye!" ); // No tr close(); return; } // connected to client if ( Connected == state ) 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; } // 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; } // ACCESS CONTROL COMMANDS // Only an ALLO sent immediately before STOR is valid. if ( cmd != "STOR" ) storFileSize = -1; // account (ACCT) if ( cmd == "ACCT" ) { // 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 } // 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 } // structure mount (SMNT) else if ( cmd == "SMNT" ) { // 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 } // 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 } // 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 ) +")" ); } // 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 } // 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 } // 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 } // 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 { qDebug("550 Requested action not taken"); 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 // store unique (STOU) else if ( cmd == "STOU" ) { send( "502 Command not implemented" ); // No tr } // append (APPE) else if ( cmd == "APPE" ) { send( "502 Command not implemented" ); // No tr } // allocate (ALLO) else if ( cmd == "ALLO" ) { storFileSize = args.toInt(); send( "200 Command okay" ); // No tr } // restart (REST) else if ( cmd == "REST" ) { 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 } } // 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 } } // 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 } // 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 } } } // 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 } } // make directory (MKD) else if ( cmd == "MKD" ) { if ( args.isEmpty() ) { qDebug(" Error: no arg"); 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() +"\"" ); } // 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 } // 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) ) { qDebug("du process failed; just sending back 1K"); send( "213 1024"); } else { QString size = out.left( out.find("\t") ); int guess = size.toInt()/5; if ( filePath.contains("doc") ) // No tr guess *= 1000; qDebug("sending back gzip guess of %d", guess); send( "213 " + QString::number(guess) ); } } } } // name list (NLST) else if ( cmd == "NLST" ) { send( "502 Command not implemented" ); // No tr } // site parameters (SITE) else if ( cmd == "SITE" ) { send( "502 Command not implemented" ); // No tr } // system (SYST) else if ( cmd == "SYST" ) { send( "215 UNIX Type: L8" ); // No tr } // status (STAT) else if ( cmd == "STAT" ) { send( "502 Command not implemented" ); // No tr } // help (HELP ) else if ( cmd == "HELP" ) { send( "502 Command not implemented" ); // No tr } // noop (NOOP) else if ( cmd == "NOOP" ) { send( "200 Command okay" ); // No tr } // not implemented else 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 ); } 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() ); return true; } return false; } void ServerPI::sendFile( const QString& file ) { if ( passiv ) { wait[SendFile] = TRUE; waitfile = file; if ( waitsocket ) newConnection( waitsocket ); } else { QStringList targets; if ( backupRestoreGzip( file, targets ) ) 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 ); } else { QStringList targets; if ( backupRestoreGzip( file, targets ) ) dtp->retrieveGzipFile( file, peeraddress, peerport ); else 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() ); 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; } } 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; QTextStream ts( &buffer ); QString fn = arg; if ( fn.isEmpty() ) fn = directory.path(); QFileInfo fi( fn ); if ( !fi.exists() ) return FALSE; // return file listing if ( fi.isFile() ) { ts << fileListing( &fi ) << endl; } // return directory listing else if ( fi.isDir() ) { QDir dir( fn ); const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); QFileInfoListIterator it( *list ); QFileInfo *info; 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 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 ); } else 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"; else if ( info->isSymLink() ) s += "l"; else s += "-"; // permisson string s += permissionString( info ) + " "; // number of hardlinks int subdirs = 1; if ( info->isDir() ) 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()); s += o.leftJustify( 8, ' ', TRUE ) + " "; // group QString g = info->group(); if ( g.isEmpty() ) 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 ) + " "; // 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 ) { //qDebug( "New incomming connection" ); if ( !passiv ) return; if ( wait[SendFile] ) { QStringList targets; if ( backupRestoreGzip( waitfile, targets ) ) dtp->sendGzipFile( waitfile, targets ); else dtp->sendFile( waitfile ); dtp->setSocket( socket ); } else if ( wait[RetrieveFile] ) { qDebug("check retrieve file"); if ( backupRestoreGzip( waitfile ) ) dtp->retrieveGzipFile( waitfile ); else dtp->retrieveFile( waitfile, storFileSize ); dtp->setSocket( socket ); } else if ( wait[SendByteArray] ) { dtp->sendByteArray( waitarray ); dtp->setSocket( socket ); } else if ( wait[RetrieveByteArray] ) { qDebug("retrieve byte array"); dtp->retrieveByteArray(); dtp->setSocket( socket ); } else waitsocket = socket; for( int i = 0; i < 4; i++ ) wait[i] = FALSE; } QString ServerPI::absFilePath( const QString& file ) { if ( file.isEmpty() ) return file; QString filepath( file ); if ( file[0] != "/" ) 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() ) ); connect( retrieveTargzProc, SIGNAL( processExited() ), 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 ) { qDebug( "STOR incomplete" ); file.remove(); } } else { file.close(); } createTargzProc->kill(); } void ServerDTP::extractTarDone() { qDebug("extract done"); #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; } //qDebug( "Debug: Sending file '%s'", file.name().latin1() ); 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 ); } } break; case SendGzipFile: if ( createTargzProc->isRunning() ) { // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY qWarning("Previous tar --gzip process is still running; killing it..."); createTargzProc->kill(); } bytes_written = 0; qDebug("==>start send tar process"); if ( !createTargzProc->start() ) qWarning("Error starting %s", createTargzProc->arguments().join(" ").latin1()); break; case SendBuffer: if ( !buf.open( IO_ReadOnly) ) { emit failed(); mode = Idle; return; } // qDebug( "Debug: Sending byte array" ); 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; } // qDebug( "Debug: Retrieving file %s", file.name().latin1() ); break; case RetrieveGzipFile: qDebug("=-> starting tar process to receive .tgz file"); break; case RetrieveBuffer: // retrieve buffer mode if ( !buf.open( IO_WriteOnly) ) { emit failed(); mode = Idle; return; } // qDebug( "Debug: Retrieving byte array" ); break; case Idle: qDebug("connection established but mode set to Idle; BUG!"); break; } } void ServerDTP::connectionClosed() { //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written ); // send file mode if ( SendFile == mode ) { 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(); } // retrieve file mode else if ( RetrieveFile == mode ) { file.close(); if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { qDebug( "STOR incomplete" ); file.remove(); emit failed(); } else { emit completed(); } } else if ( RetrieveGzipFile == mode ) { qDebug("Done writing ungzip file; closing input"); retrieveTargzProc->flushStdin(); retrieveTargzProc->closeStdin(); } // retrieve buffer mode else if ( RetrieveBuffer == mode ) { buf.close(); emit completed(); } mode = Idle; diff --git a/core/launcher/wait.cpp b/core/launcher/wait.cpp index ab53a07..34ffd1a 100644 --- a/core/launcher/wait.cpp +++ b/core/launcher/wait.cpp @@ -1,78 +1,78 @@ /********************************************************************** ** 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 "wait.h" #include <qtopia/resource.h> #include <qtopia/config.h> -#include <opie/owait.h> +#include <opie2/owait.h> #include <qwidget.h> #include <qpixmap.h> #include <qpainter.h> Wait *lastWaitObject = NULL; Wait::Wait( QWidget *parent ) : QWidget( parent ), pm( Resource::loadPixmap( "wait" ) ), waiting( FALSE ) { setFixedSize( pm.size() ); lastWaitObject = this; m_centralWait = new OWait( 0l ); m_centralWait->hide(); hide(); } Wait *Wait::getWaitObject() { return lastWaitObject; } void Wait::setWaiting( bool w ) { Config cfg ( "Launcher" ); cfg.setGroup("GUI"); waiting = w; if ( w ) { if ( cfg. readBoolEntry( "BigBusy" ) ) m_centralWait->show(); else show(); }else{ m_centralWait->hide(); hide(); } } void Wait::paintEvent( QPaintEvent * ) { QPainter p( this ); p.drawPixmap( 0, 0, pm ); } |