author | brad <brad> | 2004-03-21 12:37:03 (UTC) |
---|---|---|
committer | brad <brad> | 2004-03-21 12:37:03 (UTC) |
commit | 2560326d09f90f0afce24577cafbfd4c1f5e4b23 (patch) (side-by-side diff) | |
tree | b42de41c7b4921d4e66bec401ab387503a8d085d /core | |
parent | 2cf96daa9f9a2dca736baa6b5935c3de3e065f1b (diff) | |
download | opie-2560326d09f90f0afce24577cafbfd4c1f5e4b23.zip opie-2560326d09f90f0afce24577cafbfd4c1f5e4b23.tar.gz opie-2560326d09f90f0afce24577cafbfd4c1f5e4b23.tar.bz2 |
Initial commit of qtpoia symlinker app for opie
-rw-r--r-- | core/launcher/server.cpp | 2 | ||||
-rw-r--r-- | core/symlinker/Makefile | 160 | ||||
-rw-r--r-- | core/symlinker/config.in | 5 | ||||
-rw-r--r-- | core/symlinker/main.cpp | 160 | ||||
-rw-r--r-- | core/symlinker/opie-symlinker.control | 9 | ||||
-rw-r--r-- | core/symlinker/symlinker.pro | 15 |
6 files changed, 350 insertions, 1 deletions
diff --git a/core/launcher/server.cpp b/core/launcher/server.cpp index 634082b..9a86a80 100644 --- a/core/launcher/server.cpp +++ b/core/launcher/server.cpp @@ -519,211 +519,211 @@ void Server::systemMsg(const QCString &msg, const QByteArray &data) 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" ); + system( "opie-update-symlinks" ); serverGui->storageChanged( storage->fileSystems() ); docList->storageChanged(); } void Server::preloadApps() { Config cfg("Launcher"); cfg.setGroup("Preload"); QStringList apps = cfg.readListEntry("Apps",','); for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) { #ifndef QT_NO_COP QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()"); #endif } } diff --git a/core/symlinker/Makefile b/core/symlinker/Makefile new file mode 100644 index 0000000..f35292c --- a/dev/null +++ b/core/symlinker/Makefile @@ -0,0 +1,160 @@ +############################################################################# +# Makefile for building: $(OPIEDIR)/bin/opie-update-symlinks +# Generated by qmake (1.05a) (Qt 3.1.2) on: Tue Mar 16 10:46:29 2004 +# Project: symlinker.pro +# Template: app +# Command: $(QMAKE) -o Makefile symlinker.pro +############################################################################# + +####### Compiler, tools and options + +CC = arm-linux-gcc +CXX = arm-linux-g++ -DQT_QWS_IPAQ +LEX = flex +YACC = yacc +CFLAGS = -pipe $(CFLAGS_EXTRA) -Wall -W $(if $(CFLAGS_RELEASE),$(CFLAGS_RELEASE), -O2) -DUSE_REALTIME_AUDIO_THREAD -DOPIE_NEW_MALLOC -DOPIE_SOUND_FRAGMENT_SHIFT=14 -DOPIE_WE_VERSION=15 -DQT_NO_DEBUG +CXXFLAGS = -pipe $(CFLAGS_EXTRA) -DQWS -fno-exceptions -fno-rtti $(CXXFLAGS_EXTRA) -Wall -W $(if $(CFLAGS_RELEASE),$(CFLAGS_RELEASE), -O2) -DUSE_REALTIME_AUDIO_THREAD -DOPIE_NEW_MALLOC -DOPIE_SOUND_FRAGMENT_SHIFT=14 -DOPIE_WE_VERSION=15 -DQT_NO_DEBUG +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -I/opt/arm/opie//mkspecs/qws/linux-ipaq-g++ -I. -I$(OPIEDIR)/include -I$(QTDIR)/include -I.moc/$(PLATFORM)/ +LINK = arm-linux-gcc +LFLAGS = $(LFLAGS_EXTRA) -Wl,-rpath=$(OPIEDIR)/lib +LIBS = $(SUBLIBS) -Wl,-rpath-link,$(OPIEDIR)/lib -L$(OPIEDIR)/lib -Wl,-rpath-link,$(QTDIR)/lib -L$(QTDIR)/lib $(LIBS_EXTRA) -lqpe -lopie -lqte +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = rm -f +SYMLINK = ln -sf +DEL_DIR = rmdir +MOVE = mv -f +PRO = symlinker.pro +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p + +####### Output directory + +OBJECTS_DIR = .obj/$(PLATFORM)/ + +####### Files + +HEADERS = +SOURCES = main.cpp +OBJECTS = .obj/$(PLATFORM)/main.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = +DIST = ../../gen.pro \ + ../../include.pro \ + symlinker.pro +QMAKE_TARGET = opie-update-symlinks +DESTDIR = $(OPIEDIR)/bin/ +TARGET = $(OPIEDIR)/bin/opie-update-symlinks + +first: all +####### Implicit rules + +.SUFFIXES: .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: Makefile $(TARGET) + +$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) + test -d $(OPIEDIR)/bin/ || mkdir -p $(OPIEDIR)/bin/ + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) + +mocables: $(SRCMOC) + +$(MOC): + ( cd $(QTDIR)/src/moc ; $(MAKE) ) + +Makefile: symlinker.pro /opt/arm/opie//mkspecs/qws/linux-ipaq-g++/qmake.conf ../../gen.pro \ + ../../include.pro + $(QMAKE) -o Makefile symlinker.pro +qmake: + @$(QMAKE) -o Makefile symlinker.pro + +dist: + @mkdir -p .obj/$(PLATFORM)/opie-update-symlinks && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) .obj/$(PLATFORM)/opie-update-symlinks/ && ( cd `dirname .obj/$(PLATFORM)/opie-update-symlinks` && $(TAR) opie-update-symlinks.tar opie-update-symlinks && $(GZIP) opie-update-symlinks.tar ) && $(MOVE) `dirname .obj/$(PLATFORM)/opie-update-symlinks`/opie-update-symlinks.tar.gz . && $(DEL_FILE) -r .obj/$(PLATFORM)/opie-update-symlinks + +mocclean: + +uiclean: + +yaccclean: +lexclean: +clean: + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) $(OPIEDIR)/bin/$(TARGET) $(TARGET) + + +lupdate: + lupdate -noobsolete $(PRO) + +lrelease: + lrelease $(PRO) + +ipk: + tmp=`mktemp -d /tmp/ipkg-opie.XXXXXXXXXX` && ( $(MAKE) INSTALL_ROOT="" install && ipkg-build ; rm -rf ; ) + +opie-lupdate: + opie-lupdate $(PRO) + +opie-lrelease: + opie-lrelease $(PRO) + +messages: + xgettext -C -n -ktr -kQT_TRANSLATE_NOOP main.cpp -o '$(OPIEDIR)/messages-$(QMAKE_TARGET)-tr.po' && xgettext -C -n -a main.cpp -o '$(OPIEDIR)/messages-$(QMAKE_TARGET)-allstrings.po' + +FORCE: + +####### Compile + +.obj/$(PLATFORM)/main.o: main.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/$(PLATFORM)/main.o main.cpp + +####### Install + +install_target: + @$(CHK_DIR_EXISTS) "$(INSTALL_ROOT)$(OPIEDIR)/bin/" || $(MKDIR) "$(INSTALL_ROOT)$(OPIEDIR)/bin/" + -$(COPY) "$(OPIEDIR)/bin/$(QMAKE_TARGET)" "$(INSTALL_ROOT)$(OPIEDIR)/bin/$(QMAKE_TARGET)" + +uninstall_target: + -$(DEL_FILE) "$(INSTALL_ROOT)$(OPIEDIR)/bin/$(QMAKE_TARGET)" + -$(DEL_DIR) "$(INSTALL_ROOT)$(OPIEDIR)/bin/" + + +install: all install_target + +uninstall: uninstall_target + diff --git a/core/symlinker/config.in b/core/symlinker/config.in new file mode 100644 index 0000000..a378d3a --- a/dev/null +++ b/core/symlinker/config.in @@ -0,0 +1,5 @@ + config SYMLINKER + boolean "Opie Symlinker for external media" + default "y" + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE && LAUNCHER + diff --git a/core/symlinker/main.cpp b/core/symlinker/main.cpp new file mode 100644 index 0000000..73d5166 --- a/dev/null +++ b/core/symlinker/main.cpp @@ -0,0 +1,160 @@ +#include <qapplication.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qtextstream.h> +#include <qstringlist.h> + +#include <stdlib.h> +#include <unistd.h> //symlink() +#include <sys/stat.h> // mkdir() + +#include <sys/vfs.h> +#include <mntent.h> + +static const char *listDir = "/usr/lib/ipkg/externinfo/"; + +static void createSymlinks( const QString &location, const QString &package ) +{ + QFile inFile( location + "/usr/lib/ipkg/info/" + package + ".list" ); + mkdir( "/usr/lib/ipkg", 0777 ); + mkdir( listDir, 0777 ); + + QFile outFile( listDir + package + ".list"); + + //qDebug( "createSymlinks %s -> %s", inFile.name().ascii(), outFile.name().ascii() ); + + + + if ( inFile.open(IO_ReadOnly) && outFile.open(IO_WriteOnly)) { + QTextStream in(&inFile); + QTextStream out(&outFile); + + QString s; + while ( !in.eof() ) { // until end of file... + s = in.readLine(); // line of text excluding '\n' + //qDebug( "Read: %s", s.ascii() ); + // for s, do link/mkdir. + if ( s.right(1) == "/" ) { + //qDebug("do mkdir for %s", s.ascii()); + mkdir( s.ascii(), 0777 ); + //possible optimization: symlink directories + //that don't exist already. -- Risky. + } else { + //qDebug("do symlink for %s", s.ascii()); + QFileInfo ffi( s ); + //Don't try to symlink if a regular file exists already + if ( !ffi.exists() || ffi.isSymLink() ) { + symlink( (location+s).ascii(), s.ascii() ); +// qDebug ( "Created %s" ,s.ascii() ); + out << s << "\n"; + } //else { + // qDebug( "%s exists already, not symlinked", s.ascii() ); +// } + } + } + inFile.close(); + outFile.close(); + } +} + + + +static void removeSymlinks( const QString &package ) +{ + QFile inFile( listDir + package + ".list" ); + + if ( inFile.open(IO_ReadOnly) ) { + QTextStream in(&inFile); + + QString s; + while ( !in.eof() ) { // until end of file... + s = in.readLine(); // line of text excluding '\n' + //qDebug("remove symlink %s", s.ascii()); + QFileInfo ffi( s ); + //Confirm that it's still a symlink. + if ( ffi.isSymLink() ) + unlink( s.ascii() ); +// qDebug ( "Removed %s", s.ascii() ); +// else +// qDebug( "Not removed %s", s.ascii() ); + } + inFile.close(); + inFile.remove(); + } +} + + + +/* + Slightly hacky: we can't use StorageInfo, since we don't have a + QApplication. We look for filesystems that have the directory + /usr/lib/ipkg/info, and assume that they are removable media + with packages installed. This is safe even if eg. /usr is on a + separate filesystem, since then we would be testing for + /usr/usr/lib/ipkg/info, which should not exist. (And if it + does they deserve to have it treated as removable.) + */ + +static void updateSymlinks() +{ + QDir lists( listDir ); + QStringList knownPackages = lists.entryList( "*.list" ); // No tr + + struct mntent *me; + FILE *mntfp = setmntent( "/etc/mtab", "r" ); + + if ( mntfp ) { + while ( (me = getmntent( mntfp )) != 0 ) { + QString root = me->mnt_dir; + if ( root == "/" ) + continue; + + QString info = root + "/usr/lib/ipkg/info"; + QDir infoDir( info ); + //qDebug( "looking at %s", info.ascii() ); + if ( infoDir.isReadable() ) { + const QFileInfoList *packages = infoDir.entryInfoList( "*.list" ); // No tr + QFileInfoListIterator it( *packages ); + QFileInfo *fi; + while (( fi = *it )) { + ++it; + if ( knownPackages.contains( fi->fileName() ) ) { + //qDebug( "found %s and we've seen it before", fi->fileName().latin1() ); + knownPackages.remove( fi->fileName() ); + } else { + //it's a new one + createSymlinks( root, fi->baseName() ); + } + + } + + } + } + endmntent( mntfp ); + } + + for ( QStringList::Iterator it = knownPackages.begin(); + it != knownPackages.end(); ++it ) { + // strip ".info" off the end. + removeSymlinks( (*it).left((*it).length()-5) ); + } +} + + + +int main( int argc, char *argv[] ) +{ + QApplication a( argc, argv, QApplication::Tty ); + + QString command = argc > 1 ? argv[1] : "update"; // No tr + + if ( command == "update" ) // No tr + updateSymlinks(); + else if ( command == "create" && argc > 3 ) // No tr + createSymlinks( argv[2], argv[3] ); + else if ( command == "remove" && argc > 2 ) // No tr + removeSymlinks( argv[2] ); + else + qWarning( "Argument error" ); +} diff --git a/core/symlinker/opie-symlinker.control b/core/symlinker/opie-symlinker.control new file mode 100644 index 0000000..6378653 --- a/dev/null +++ b/core/symlinker/opie-symlinker.control @@ -0,0 +1,9 @@ +Package: opie-symlinker +Files: bin/opie-update-symlinks +Priority: optional +Section: opie/system +Maintainer: Project Opie <opie@handhelds.org> +Architecture: arm +Version: $QPE_VERSION-$SUB_VERSION.3 +Depends: task-opie-minimal +Description: Enables apps on external media diff --git a/core/symlinker/symlinker.pro b/core/symlinker/symlinker.pro new file mode 100644 index 0000000..9558b3e --- a/dev/null +++ b/core/symlinker/symlinker.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +CONFIG += qtopia warn_on release +DESTDIR = $(OPIEDIR)/bin + +HEADERS = +SOURCES = main.cpp +INTERFACES = + +TARGET = opie-update-symlinks +INCLUDEPATH += $(OPIEDIR)/include +DEPENDPATH += $(OPIEDIR)/include . +LIBS += -lqpe -lopie + +include ( $(OPIEDIR)/include.pro ) + |