author | brad <brad> | 2004-03-29 16:57:42 (UTC) |
---|---|---|
committer | brad <brad> | 2004-03-29 16:57:42 (UTC) |
commit | e15bbcc647d8e236c5cc1539f8fcd8a4f6809c1e (patch) (unidiff) | |
tree | f8501dfa36a106437af7d09fb21e385d1d131a50 | |
parent | b34d33b14b77331c0de16d3c80f929512003f06c (diff) | |
download | opie-e15bbcc647d8e236c5cc1539f8fcd8a4f6809c1e.zip opie-e15bbcc647d8e236c5cc1539f8fcd8a4f6809c1e.tar.gz opie-e15bbcc647d8e236c5cc1539f8fcd8a4f6809c1e.tar.bz2 |
Add workaround for the new format of ipkg written list files on external media.
Works with old and new versions of ipkg now and does not touch anything set up by
other package management programs
-rw-r--r-- | core/symlinker/main.cpp | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/core/symlinker/main.cpp b/core/symlinker/main.cpp index 73d5166..6a04980 100644 --- a/core/symlinker/main.cpp +++ b/core/symlinker/main.cpp | |||
@@ -1,160 +1,179 @@ | |||
1 | #include <qapplication.h> | 1 | #include <qapplication.h> |
2 | #include <qfile.h> | 2 | #include <qfile.h> |
3 | #include <qfileinfo.h> | 3 | #include <qfileinfo.h> |
4 | #include <qdir.h> | 4 | #include <qdir.h> |
5 | #include <qtextstream.h> | 5 | #include <qtextstream.h> |
6 | #include <qstringlist.h> | 6 | #include <qstringlist.h> |
7 | 7 | ||
8 | #include <stdlib.h> | 8 | #include <stdlib.h> |
9 | #include <unistd.h> //symlink() | 9 | #include <unistd.h> //symlink() |
10 | #include <sys/stat.h> // mkdir() | 10 | #include <sys/stat.h> // mkdir() |
11 | 11 | ||
12 | #include <sys/vfs.h> | 12 | #include <sys/vfs.h> |
13 | #include <mntent.h> | 13 | #include <mntent.h> |
14 | #include <errno.h> | ||
14 | 15 | ||
15 | static const char *listDir = "/usr/lib/ipkg/externinfo/"; | 16 | static const char *listDir = "/usr/lib/ipkg/externinfo/"; |
16 | 17 | ||
17 | static void createSymlinks( const QString &location, const QString &package ) | 18 | static void createSymlinks( const QString &location, const QString &package ) |
18 | { | 19 | { |
20 | |||
19 | QFile inFile( location + "/usr/lib/ipkg/info/" + package + ".list" ); | 21 | QFile inFile( location + "/usr/lib/ipkg/info/" + package + ".list" ); |
20 | mkdir( "/usr/lib/ipkg", 0777 ); | 22 | mkdir( "/usr/lib/ipkg", 0777 ); |
21 | mkdir( listDir, 0777 ); | 23 | mkdir( listDir, 0777 ); |
22 | 24 | ||
23 | QFile outFile( listDir + package + ".list"); | 25 | QFile outFile( listDir + package + ".list"); |
24 | 26 | ||
25 | //qDebug( "createSymlinks %s -> %s", inFile.name().ascii(), outFile.name().ascii() ); | 27 | // qDebug( "createSymlinks %s -> %s", inFile.name().ascii(), outFile.name().ascii() ); |
26 | 28 | ||
27 | 29 | ||
28 | 30 | ||
29 | if ( inFile.open(IO_ReadOnly) && outFile.open(IO_WriteOnly)) { | 31 | if ( inFile.open(IO_ReadOnly) && outFile.open(IO_WriteOnly)) { |
30 | QTextStream in(&inFile); | 32 | QTextStream in(&inFile); |
31 | QTextStream out(&outFile); | 33 | QTextStream out(&outFile); |
32 | 34 | ||
33 | QString s; | 35 | QString s; |
34 | while ( !in.eof() ) { // until end of file... | 36 | while ( !in.eof() ) { // until end of file... |
35 | s = in.readLine(); // line of text excluding '\n' | 37 | s = in.readLine(); // line of text excluding '\n' |
36 | //qDebug( "Read: %s", s.ascii() ); | 38 | // qDebug( "Read: %s", s.ascii() ); |
39 | if (s.find(location,0,true) >= 0){ | ||
40 | // qDebug( "Found!" ); | ||
41 | s = s.replace(location,""); | ||
42 | } | ||
43 | // qDebug( "Read after: %s", s.ascii() ); | ||
44 | |||
37 | // for s, do link/mkdir. | 45 | // for s, do link/mkdir. |
38 | if ( s.right(1) == "/" ) { | 46 | if ( s.right(1) == "/" ) { |
39 | //qDebug("do mkdir for %s", s.ascii()); | 47 | // qDebug("do mkdir for %s", s.ascii()); |
40 | mkdir( s.ascii(), 0777 ); | 48 | mkdir( s.ascii(), 0777 ); |
41 | //possible optimization: symlink directories | 49 | //possible optimization: symlink directories |
42 | //that don't exist already. -- Risky. | 50 | //that don't exist already. -- Risky. |
43 | } else { | 51 | } else { |
44 | //qDebug("do symlink for %s", s.ascii()); | 52 | // qDebug("do symlink for %s", s.ascii()); |
45 | QFileInfo ffi( s ); | 53 | QFileInfo ffi( s ); |
46 | //Don't try to symlink if a regular file exists already | 54 | //Don't try to symlink if a regular file exists already |
47 | if ( !ffi.exists() || ffi.isSymLink() ) { | 55 | if ( !ffi.exists() || ffi.isSymLink() ) { |
48 | symlink( (location+s).ascii(), s.ascii() ); | 56 | if (symlink( (location+s).ascii(), s.ascii() ) != 0){ |
57 | if (errno == ENOENT){ | ||
58 | // perror("Symlink Failed! "); | ||
59 | QString e=s.ascii(); | ||
60 | e = e.replace(ffi.fileName(),""); | ||
61 | // qDebug("DirName : %s",e.ascii() ); | ||
62 | system ( QString("mkdir -p ")+e.ascii() ); | ||
63 | if (symlink( (location+s).ascii(), s.ascii() ) != 0) | ||
64 | qDebug ("Big problem creating symlink and directory"); | ||
65 | } | ||
66 | } | ||
49 | // qDebug ( "Created %s" ,s.ascii() ); | 67 | // qDebug ( "Created %s" ,s.ascii() ); |
50 | out << s << "\n"; | 68 | out << s << "\n"; |
51 | } //else { | 69 | } else { |
52 | // qDebug( "%s exists already, not symlinked", s.ascii() ); | 70 | qDebug( "%s exists already, not symlinked", s.ascii() ); |
53 | // } | 71 | } |
54 | } | 72 | } |
55 | } | 73 | } |
56 | inFile.close(); | 74 | inFile.close(); |
57 | outFile.close(); | 75 | outFile.close(); |
58 | } | 76 | } |
59 | } | 77 | } |
60 | 78 | ||
61 | 79 | ||
62 | 80 | ||
63 | static void removeSymlinks( const QString &package ) | 81 | static void removeSymlinks( const QString &package ) |
64 | { | 82 | { |
65 | QFile inFile( listDir + package + ".list" ); | 83 | QFile inFile( listDir + package + ".list" ); |
66 | 84 | ||
67 | if ( inFile.open(IO_ReadOnly) ) { | 85 | if ( inFile.open(IO_ReadOnly) ) { |
68 | QTextStream in(&inFile); | 86 | QTextStream in(&inFile); |
69 | 87 | ||
70 | QString s; | 88 | QString s; |
71 | while ( !in.eof() ) { // until end of file... | 89 | while ( !in.eof() ) { // until end of file... |
72 | s = in.readLine(); // line of text excluding '\n' | 90 | s = in.readLine(); // line of text excluding '\n' |
73 | //qDebug("remove symlink %s", s.ascii()); | 91 | // qDebug("remove symlink %s", s.ascii()); |
74 | QFileInfo ffi( s ); | 92 | QFileInfo ffi( s ); |
75 | //Confirm that it's still a symlink. | 93 | //Confirm that it's still a symlink. |
76 | if ( ffi.isSymLink() ) | 94 | if ( ffi.isSymLink() ){ |
77 | unlink( s.ascii() ); | 95 | unlink( s.ascii() ); |
78 | // qDebug ( "Removed %s", s.ascii() ); | 96 | // qDebug ( "Removed %s", s.ascii() );} |
79 | // else | 97 | // else |
80 | // qDebug( "Not removed %s", s.ascii() ); | 98 | // qDebug( "Not removed %s", s.ascii() ); |
99 | } | ||
81 | } | 100 | } |
82 | inFile.close(); | 101 | inFile.close(); |
83 | inFile.remove(); | 102 | inFile.remove(); |
84 | } | 103 | } |
85 | } | 104 | } |
86 | 105 | ||
87 | 106 | ||
88 | 107 | ||
89 | /* | 108 | /* |
90 | Slightly hacky: we can't use StorageInfo, since we don't have a | 109 | Slightly hacky: we can't use StorageInfo, since we don't have a |
91 | QApplication. We look for filesystems that have the directory | 110 | QApplication. We look for filesystems that have the directory |
92 | /usr/lib/ipkg/info, and assume that they are removable media | 111 | /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 | 112 | with packages installed. This is safe even if eg. /usr is on a |
94 | separate filesystem, since then we would be testing for | 113 | separate filesystem, since then we would be testing for |
95 | /usr/usr/lib/ipkg/info, which should not exist. (And if it | 114 | /usr/usr/lib/ipkg/info, which should not exist. (And if it |
96 | does they deserve to have it treated as removable.) | 115 | does they deserve to have it treated as removable.) |
97 | */ | 116 | */ |
98 | 117 | ||
99 | static void updateSymlinks() | 118 | static void updateSymlinks() |
100 | { | 119 | { |
101 | QDir lists( listDir ); | 120 | QDir lists( listDir ); |
102 | QStringList knownPackages = lists.entryList( "*.list" ); // No tr | 121 | QStringList knownPackages = lists.entryList( "*.list" ); // No tr |
103 | 122 | ||
104 | struct mntent *me; | 123 | struct mntent *me; |
105 | FILE *mntfp = setmntent( "/etc/mtab", "r" ); | 124 | FILE *mntfp = setmntent( "/etc/mtab", "r" ); |
106 | 125 | ||
107 | if ( mntfp ) { | 126 | if ( mntfp ) { |
108 | while ( (me = getmntent( mntfp )) != 0 ) { | 127 | while ( (me = getmntent( mntfp )) != 0 ) { |
109 | QString root = me->mnt_dir; | 128 | QString root = me->mnt_dir; |
110 | if ( root == "/" ) | 129 | if ( root == "/" ) |
111 | continue; | 130 | continue; |
112 | 131 | ||
113 | QString info = root + "/usr/lib/ipkg/info"; | 132 | QString info = root + "/usr/lib/ipkg/info"; |
114 | QDir infoDir( info ); | 133 | QDir infoDir( info ); |
115 | //qDebug( "looking at %s", info.ascii() ); | 134 | // qDebug( "looking at %s", info.ascii() ); |
116 | if ( infoDir.isReadable() ) { | 135 | if ( infoDir.isReadable() ) { |
117 | const QFileInfoList *packages = infoDir.entryInfoList( "*.list" ); // No tr | 136 | const QFileInfoList *packages = infoDir.entryInfoList( "*.list" ); // No tr |
118 | QFileInfoListIterator it( *packages ); | 137 | QFileInfoListIterator it( *packages ); |
119 | QFileInfo *fi; | 138 | QFileInfo *fi; |
120 | while (( fi = *it )) { | 139 | while (( fi = *it )) { |
121 | ++it; | 140 | ++it; |
122 | if ( knownPackages.contains( fi->fileName() ) ) { | 141 | if ( knownPackages.contains( fi->fileName() ) ) { |
123 | //qDebug( "found %s and we've seen it before", fi->fileName().latin1() ); | 142 | // qDebug( "found %s and we've seen it before", fi->fileName().latin1() ); |
124 | knownPackages.remove( fi->fileName() ); | 143 | knownPackages.remove( fi->fileName() ); |
125 | } else { | 144 | } else { |
126 | //it's a new one | 145 | //it's a new one |
127 | createSymlinks( root, fi->baseName() ); | 146 | createSymlinks( root, fi->baseName() ); |
128 | } | 147 | } |
129 | 148 | ||
130 | } | 149 | } |
131 | 150 | ||
132 | } | 151 | } |
133 | } | 152 | } |
134 | endmntent( mntfp ); | 153 | endmntent( mntfp ); |
135 | } | 154 | } |
136 | 155 | ||
137 | for ( QStringList::Iterator it = knownPackages.begin(); | 156 | for ( QStringList::Iterator it = knownPackages.begin(); |
138 | it != knownPackages.end(); ++it ) { | 157 | it != knownPackages.end(); ++it ) { |
139 | // strip ".info" off the end. | 158 | // strip ".info" off the end. |
140 | removeSymlinks( (*it).left((*it).length()-5) ); | 159 | removeSymlinks( (*it).left((*it).length()-5) ); |
141 | } | 160 | } |
142 | } | 161 | } |
143 | 162 | ||
144 | 163 | ||
145 | 164 | ||
146 | int main( int argc, char *argv[] ) | 165 | int main( int argc, char *argv[] ) |
147 | { | 166 | { |
148 | QApplication a( argc, argv, QApplication::Tty ); | 167 | QApplication a( argc, argv, QApplication::Tty ); |
149 | 168 | ||
150 | QString command = argc > 1 ? argv[1] : "update"; // No tr | 169 | QString command = argc > 1 ? argv[1] : "update"; // No tr |
151 | 170 | ||
152 | if ( command == "update" ) // No tr | 171 | if ( command == "update" ) // No tr |
153 | updateSymlinks(); | 172 | updateSymlinks(); |
154 | else if ( command == "create" && argc > 3 ) // No tr | 173 | else if ( command == "create" && argc > 3 ) // No tr |
155 | createSymlinks( argv[2], argv[3] ); | 174 | createSymlinks( argv[2], argv[3] ); |
156 | else if ( command == "remove" && argc > 2 ) // No tr | 175 | else if ( command == "remove" && argc > 2 ) // No tr |
157 | removeSymlinks( argv[2] ); | 176 | removeSymlinks( argv[2] ); |
158 | else | 177 | else |
159 | qWarning( "Argument error" ); | 178 | qWarning( "Argument error" ); |
160 | } | 179 | } |