-rw-r--r-- | config.in | 1 | ||||
-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 | ||||
-rw-r--r-- | packages | 1 |
8 files changed, 352 insertions, 1 deletions
@@ -157,2 +157,3 @@ menu "Base" | |||
157 | source core/qws/config.in | 157 | source core/qws/config.in |
158 | source core/symlinker/config.in | ||
158 | endmenu | 159 | endmenu |
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 | |||
@@ -710,3 +710,3 @@ void Server::storageChanged() | |||
710 | { | 710 | { |
711 | system( "qtopia-update-symlinks" ); | 711 | system( "opie-update-symlinks" ); |
712 | serverGui->storageChanged( storage->fileSystems() ); | 712 | serverGui->storageChanged( storage->fileSystems() ); |
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 @@ | |||
1 | ############################################################################# | ||
2 | # Makefile for building: $(OPIEDIR)/bin/opie-update-symlinks | ||
3 | # Generated by qmake (1.05a) (Qt 3.1.2) on: Tue Mar 16 10:46:29 2004 | ||
4 | # Project: symlinker.pro | ||
5 | # Template: app | ||
6 | # Command: $(QMAKE) -o Makefile symlinker.pro | ||
7 | ############################################################################# | ||
8 | |||
9 | ####### Compiler, tools and options | ||
10 | |||
11 | CC = arm-linux-gcc | ||
12 | CXX = arm-linux-g++ -DQT_QWS_IPAQ | ||
13 | LEX = flex | ||
14 | YACC = yacc | ||
15 | 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 | ||
16 | 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 | ||
17 | LEXFLAGS = | ||
18 | YACCFLAGS= -d | ||
19 | INCPATH = -I/opt/arm/opie//mkspecs/qws/linux-ipaq-g++ -I. -I$(OPIEDIR)/include -I$(QTDIR)/include -I.moc/$(PLATFORM)/ | ||
20 | LINK = arm-linux-gcc | ||
21 | LFLAGS = $(LFLAGS_EXTRA) -Wl,-rpath=$(OPIEDIR)/lib | ||
22 | LIBS = $(SUBLIBS) -Wl,-rpath-link,$(OPIEDIR)/lib -L$(OPIEDIR)/lib -Wl,-rpath-link,$(QTDIR)/lib -L$(QTDIR)/lib $(LIBS_EXTRA) -lqpe -lopie -lqte | ||
23 | AR = ar cqs | ||
24 | RANLIB = | ||
25 | MOC = $(QTDIR)/bin/moc | ||
26 | UIC = $(QTDIR)/bin/uic | ||
27 | QMAKE = qmake | ||
28 | TAR = tar -cf | ||
29 | GZIP = gzip -9f | ||
30 | COPY = cp -f | ||
31 | COPY_FILE= $(COPY) -p | ||
32 | COPY_DIR = $(COPY) -pR | ||
33 | DEL_FILE = rm -f | ||
34 | SYMLINK = ln -sf | ||
35 | DEL_DIR = rmdir | ||
36 | MOVE = mv -f | ||
37 | PRO = symlinker.pro | ||
38 | CHK_DIR_EXISTS= test -d | ||
39 | MKDIR = mkdir -p | ||
40 | |||
41 | ####### Output directory | ||
42 | |||
43 | OBJECTS_DIR = .obj/$(PLATFORM)/ | ||
44 | |||
45 | ####### Files | ||
46 | |||
47 | HEADERS = | ||
48 | SOURCES = main.cpp | ||
49 | OBJECTS = .obj/$(PLATFORM)/main.o | ||
50 | FORMS = | ||
51 | UICDECLS = | ||
52 | UICIMPLS = | ||
53 | SRCMOC = | ||
54 | OBJMOC = | ||
55 | DIST = ../../gen.pro \ | ||
56 | ../../include.pro \ | ||
57 | symlinker.pro | ||
58 | QMAKE_TARGET = opie-update-symlinks | ||
59 | DESTDIR = $(OPIEDIR)/bin/ | ||
60 | TARGET = $(OPIEDIR)/bin/opie-update-symlinks | ||
61 | |||
62 | first: all | ||
63 | ####### Implicit rules | ||
64 | |||
65 | .SUFFIXES: .c .cpp .cc .cxx .C | ||
66 | |||
67 | .cpp.o: | ||
68 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
69 | |||
70 | .cc.o: | ||
71 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
72 | |||
73 | .cxx.o: | ||
74 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
75 | |||
76 | .C.o: | ||
77 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
78 | |||
79 | .c.o: | ||
80 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
81 | |||
82 | ####### Build rules | ||
83 | |||
84 | all: Makefile $(TARGET) | ||
85 | |||
86 | $(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) | ||
87 | test -d $(OPIEDIR)/bin/ || mkdir -p $(OPIEDIR)/bin/ | ||
88 | $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
89 | |||
90 | mocables: $(SRCMOC) | ||
91 | |||
92 | $(MOC): | ||
93 | ( cd $(QTDIR)/src/moc ; $(MAKE) ) | ||
94 | |||
95 | Makefile: symlinker.pro /opt/arm/opie//mkspecs/qws/linux-ipaq-g++/qmake.conf ../../gen.pro \ | ||
96 | ../../include.pro | ||
97 | $(QMAKE) -o Makefile symlinker.pro | ||
98 | qmake: | ||
99 | @$(QMAKE) -o Makefile symlinker.pro | ||
100 | |||
101 | dist: | ||
102 | @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 | ||
103 | |||
104 | mocclean: | ||
105 | |||
106 | uiclean: | ||
107 | |||
108 | yaccclean: | ||
109 | lexclean: | ||
110 | clean: | ||
111 | -$(DEL_FILE) $(OBJECTS) | ||
112 | -$(DEL_FILE) *~ core *.core | ||
113 | |||
114 | |||
115 | ####### Sub-libraries | ||
116 | |||
117 | distclean: clean | ||
118 | -$(DEL_FILE) $(OPIEDIR)/bin/$(TARGET) $(TARGET) | ||
119 | |||
120 | |||
121 | lupdate: | ||
122 | lupdate -noobsolete $(PRO) | ||
123 | |||
124 | lrelease: | ||
125 | lrelease $(PRO) | ||
126 | |||
127 | ipk: | ||
128 | tmp=`mktemp -d /tmp/ipkg-opie.XXXXXXXXXX` && ( $(MAKE) INSTALL_ROOT="" install && ipkg-build ; rm -rf ; ) | ||
129 | |||
130 | opie-lupdate: | ||
131 | opie-lupdate $(PRO) | ||
132 | |||
133 | opie-lrelease: | ||
134 | opie-lrelease $(PRO) | ||
135 | |||
136 | messages: | ||
137 | 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' | ||
138 | |||
139 | FORCE: | ||
140 | |||
141 | ####### Compile | ||
142 | |||
143 | .obj/$(PLATFORM)/main.o: main.cpp | ||
144 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o .obj/$(PLATFORM)/main.o main.cpp | ||
145 | |||
146 | ####### Install | ||
147 | |||
148 | install_target: | ||
149 | @$(CHK_DIR_EXISTS) "$(INSTALL_ROOT)$(OPIEDIR)/bin/" || $(MKDIR) "$(INSTALL_ROOT)$(OPIEDIR)/bin/" | ||
150 | -$(COPY) "$(OPIEDIR)/bin/$(QMAKE_TARGET)" "$(INSTALL_ROOT)$(OPIEDIR)/bin/$(QMAKE_TARGET)" | ||
151 | |||
152 | uninstall_target: | ||
153 | -$(DEL_FILE) "$(INSTALL_ROOT)$(OPIEDIR)/bin/$(QMAKE_TARGET)" | ||
154 | -$(DEL_DIR) "$(INSTALL_ROOT)$(OPIEDIR)/bin/" | ||
155 | |||
156 | |||
157 | install: all install_target | ||
158 | |||
159 | uninstall: uninstall_target | ||
160 | |||
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 @@ | |||
1 | config SYMLINKER | ||
2 | boolean "Opie Symlinker for external media" | ||
3 | default "y" | ||
4 | depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE && LAUNCHER | ||
5 | |||
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 @@ | |||
1 | #include <qapplication.h> | ||
2 | #include <qfile.h> | ||
3 | #include <qfileinfo.h> | ||
4 | #include <qdir.h> | ||
5 | #include <qtextstream.h> | ||
6 | #include <qstringlist.h> | ||
7 | |||
8 | #include <stdlib.h> | ||
9 | #include <unistd.h> //symlink() | ||
10 | #include <sys/stat.h> // mkdir() | ||
11 | |||
12 | #include <sys/vfs.h> | ||
13 | #include <mntent.h> | ||
14 | |||
15 | static const char *listDir = "/usr/lib/ipkg/externinfo/"; | ||
16 | |||
17 | static void createSymlinks( const QString &location, const QString &package ) | ||
18 | { | ||
19 | QFile inFile( location + "/usr/lib/ipkg/info/" + package + ".list" ); | ||
20 | mkdir( "/usr/lib/ipkg", 0777 ); | ||
21 | mkdir( listDir, 0777 ); | ||
22 | |||
23 | QFile outFile( listDir + package + ".list"); | ||
24 | |||
25 | //qDebug( "createSymlinks %s -> %s", inFile.name().ascii(), outFile.name().ascii() ); | ||
26 | |||
27 | |||
28 | |||
29 | if ( inFile.open(IO_ReadOnly) && outFile.open(IO_WriteOnly)) { | ||
30 | QTextStream in(&inFile); | ||
31 | QTextStream out(&outFile); | ||
32 | |||
33 | QString s; | ||
34 | while ( !in.eof() ) { // until end of file... | ||
35 | s = in.readLine(); // line of text excluding '\n' | ||
36 | //qDebug( "Read: %s", s.ascii() ); | ||
37 | // for s, do link/mkdir. | ||
38 | if ( s.right(1) == "/" ) { | ||
39 | //qDebug("do mkdir for %s", s.ascii()); | ||
40 | mkdir( s.ascii(), 0777 ); | ||
41 | //possible optimization: symlink directories | ||
42 | //that don't exist already. -- Risky. | ||
43 | } else { | ||
44 | //qDebug("do symlink for %s", s.ascii()); | ||
45 | QFileInfo ffi( s ); | ||
46 | //Don't try to symlink if a regular file exists already | ||
47 | if ( !ffi.exists() || ffi.isSymLink() ) { | ||
48 | symlink( (location+s).ascii(), s.ascii() ); | ||
49 | // qDebug ( "Created %s" ,s.ascii() ); | ||
50 | out << s << "\n"; | ||
51 | } //else { | ||
52 | // qDebug( "%s exists already, not symlinked", s.ascii() ); | ||
53 | // } | ||
54 | } | ||
55 | } | ||
56 | inFile.close(); | ||
57 | outFile.close(); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | |||
62 | |||
63 | static void removeSymlinks( const QString &package ) | ||
64 | { | ||
65 | QFile inFile( listDir + package + ".list" ); | ||
66 | |||
67 | if ( inFile.open(IO_ReadOnly) ) { | ||
68 | QTextStream in(&inFile); | ||
69 | |||
70 | QString s; | ||
71 | while ( !in.eof() ) { // until end of file... | ||
72 | s = in.readLine(); // line of text excluding '\n' | ||
73 | //qDebug("remove symlink %s", s.ascii()); | ||
74 | QFileInfo ffi( s ); | ||
75 | //Confirm that it's still a symlink. | ||
76 | if ( ffi.isSymLink() ) | ||
77 | unlink( s.ascii() ); | ||
78 | // qDebug ( "Removed %s", s.ascii() ); | ||
79 | // else | ||
80 | // qDebug( "Not removed %s", s.ascii() ); | ||
81 | } | ||
82 | inFile.close(); | ||
83 | inFile.remove(); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
90 | Slightly hacky: we can't use StorageInfo, since we don't have a | ||
91 | QApplication. We look for filesystems that have the directory | ||
92 | /usr/lib/ipkg/info, and assume that they are removable media | ||
93 | with packages installed. This is safe even if eg. /usr is on a | ||
94 | separate filesystem, since then we would be testing for | ||
95 | /usr/usr/lib/ipkg/info, which should not exist. (And if it | ||
96 | does they deserve to have it treated as removable.) | ||
97 | */ | ||
98 | |||
99 | static void updateSymlinks() | ||
100 | { | ||
101 | QDir lists( listDir ); | ||
102 | QStringList knownPackages = lists.entryList( "*.list" ); // No tr | ||
103 | |||
104 | struct mntent *me; | ||
105 | FILE *mntfp = setmntent( "/etc/mtab", "r" ); | ||
106 | |||
107 | if ( mntfp ) { | ||
108 | while ( (me = getmntent( mntfp )) != 0 ) { | ||
109 | QString root = me->mnt_dir; | ||
110 | if ( root == "/" ) | ||
111 | continue; | ||
112 | |||
113 | QString info = root + "/usr/lib/ipkg/info"; | ||
114 | QDir infoDir( info ); | ||
115 | //qDebug( "looking at %s", info.ascii() ); | ||
116 | if ( infoDir.isReadable() ) { | ||
117 | const QFileInfoList *packages = infoDir.entryInfoList( "*.list" ); // No tr | ||
118 | QFileInfoListIterator it( *packages ); | ||
119 | QFileInfo *fi; | ||
120 | while (( fi = *it )) { | ||
121 | ++it; | ||
122 | if ( knownPackages.contains( fi->fileName() ) ) { | ||
123 | //qDebug( "found %s and we've seen it before", fi->fileName().latin1() ); | ||
124 | knownPackages.remove( fi->fileName() ); | ||
125 | } else { | ||
126 | //it's a new one | ||
127 | createSymlinks( root, fi->baseName() ); | ||
128 | } | ||
129 | |||
130 | } | ||
131 | |||
132 | } | ||
133 | } | ||
134 | endmntent( mntfp ); | ||
135 | } | ||
136 | |||
137 | for ( QStringList::Iterator it = knownPackages.begin(); | ||
138 | it != knownPackages.end(); ++it ) { | ||
139 | // strip ".info" off the end. | ||
140 | removeSymlinks( (*it).left((*it).length()-5) ); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | |||
146 | int main( int argc, char *argv[] ) | ||
147 | { | ||
148 | QApplication a( argc, argv, QApplication::Tty ); | ||
149 | |||
150 | QString command = argc > 1 ? argv[1] : "update"; // No tr | ||
151 | |||
152 | if ( command == "update" ) // No tr | ||
153 | updateSymlinks(); | ||
154 | else if ( command == "create" && argc > 3 ) // No tr | ||
155 | createSymlinks( argv[2], argv[3] ); | ||
156 | else if ( command == "remove" && argc > 2 ) // No tr | ||
157 | removeSymlinks( argv[2] ); | ||
158 | else | ||
159 | qWarning( "Argument error" ); | ||
160 | } | ||
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 @@ | |||
1 | Package: opie-symlinker | ||
2 | Files: bin/opie-update-symlinks | ||
3 | Priority: optional | ||
4 | Section: opie/system | ||
5 | Maintainer: Project Opie <opie@handhelds.org> | ||
6 | Architecture: arm | ||
7 | Version: $QPE_VERSION-$SUB_VERSION.3 | ||
8 | Depends: task-opie-minimal | ||
9 | 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 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG += qtopia warn_on release | ||
3 | DESTDIR = $(OPIEDIR)/bin | ||
4 | |||
5 | HEADERS = | ||
6 | SOURCES = main.cpp | ||
7 | INTERFACES= | ||
8 | |||
9 | TARGET = opie-update-symlinks | ||
10 | INCLUDEPATH += $(OPIEDIR)/include | ||
11 | DEPENDPATH += $(OPIEDIR)/include . | ||
12 | LIBS += -lqpe -lopie | ||
13 | |||
14 | include ( $(OPIEDIR)/include.pro ) | ||
15 | |||
@@ -169,2 +169,3 @@ CONFIG_SSHKEYS noncore/settings/sshkeys sshkeys.pro | |||
169 | CONFIG_SUSPENDAPPLET core/applets/suspendappletsuspendapplet.pro | 169 | CONFIG_SUSPENDAPPLET core/applets/suspendappletsuspendapplet.pro |
170 | CONFIG_SYMLINKER core/symlinker symlinker.pro | ||
170 | CONFIG_SYSINFO noncore/settings/sysinfosysinfo.pro | 171 | CONFIG_SYSINFO noncore/settings/sysinfosysinfo.pro |