Diffstat (limited to 'noncore/settings/aqpkg/ipkg.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/settings/aqpkg/ipkg.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/noncore/settings/aqpkg/ipkg.cpp b/noncore/settings/aqpkg/ipkg.cpp new file mode 100644 index 0000000..d5157eb --- a/dev/null +++ b/noncore/settings/aqpkg/ipkg.cpp | |||
@@ -0,0 +1,345 @@ | |||
1 | /*************************************************************************** | ||
2 | ipkg.cpp - description | ||
3 | ------------------- | ||
4 | begin : Sat Aug 31 2002 | ||
5 | copyright : (C) 2002 by Andy Qua | ||
6 | email : andy.qua@blueyonder.co.uk | ||
7 | ***************************************************************************/ | ||
8 | |||
9 | /*************************************************************************** | ||
10 | * * | ||
11 | * This program is free software; you can redistribute it and/or modify * | ||
12 | * it under the terms of the GNU General Public License as published by * | ||
13 | * the Free Software Foundation; either version 2 of the License, or * | ||
14 | * (at your option) any later version. * | ||
15 | * * | ||
16 | ***************************************************************************/ | ||
17 | |||
18 | #include <fstream> | ||
19 | using namespace std; | ||
20 | |||
21 | #include <stdio.h> | ||
22 | #include <unistd.h> | ||
23 | |||
24 | #ifdef QWS | ||
25 | #include <qpe/qpeapplication.h> | ||
26 | #else | ||
27 | #include <qapplication.h> | ||
28 | #endif | ||
29 | #include <qdir.h> | ||
30 | #include <qtextstream.h> | ||
31 | |||
32 | #include "utils.h" | ||
33 | #include "ipkg.h" | ||
34 | #include "global.h" | ||
35 | |||
36 | Ipkg :: Ipkg() | ||
37 | { | ||
38 | } | ||
39 | |||
40 | Ipkg :: ~Ipkg() | ||
41 | { | ||
42 | } | ||
43 | |||
44 | // Option is what we are going to do - install, upgrade, download | ||
45 | // package is the package name to install - either a fully qualified path and ipk | ||
46 | // file (if stored locally) or just the name of the package (for a network package) | ||
47 | // packageName is the package name - (for a network package this will be the same as | ||
48 | // package parameter) | ||
49 | // dest is the destination alias (from ipk.conf) | ||
50 | // destDir is the dir that the destination alias points to (used to link to root) | ||
51 | // flags is the ipkg options flags | ||
52 | // dir is the directory to run ipkg in (defaults to "") | ||
53 | bool Ipkg :: runIpkg( ) | ||
54 | { | ||
55 | bool ret = false; | ||
56 | |||
57 | QDir::setCurrent( "/tmp" ); | ||
58 | QString cmd = ""; | ||
59 | |||
60 | if ( runtimeDir != "" ) | ||
61 | { | ||
62 | cmd += "cd "; | ||
63 | cmd += runtimeDir; | ||
64 | cmd += " ; "; | ||
65 | } | ||
66 | cmd += "ipkg"; | ||
67 | |||
68 | if ( option != "update" && option != "download" ) | ||
69 | { | ||
70 | cmd += " -dest "+ destination; | ||
71 | cmd += " -force-defaults"; | ||
72 | |||
73 | if ( flags & FORCE_DEPENDS ) | ||
74 | cmd += " -force-depends"; | ||
75 | if ( flags & FORCE_REINSTALL ) | ||
76 | cmd += " -force-reinstall"; | ||
77 | if ( flags & FORCE_REMOVE ) | ||
78 | cmd += " -force-removal-of-essential-packages"; | ||
79 | if ( flags & FORCE_OVERWRITE ) | ||
80 | cmd += " -force-overwrite"; | ||
81 | |||
82 | // Handle make links | ||
83 | // Rules - If make links is switched on, create links to root | ||
84 | // if destDir is NOT / | ||
85 | if ( flags & MAKE_LINKS ) | ||
86 | { | ||
87 | // If destDir == / turn off make links as package is being insalled | ||
88 | // to root already. | ||
89 | if ( destDir == "/" ) | ||
90 | flags ^= MAKE_LINKS; | ||
91 | } | ||
92 | |||
93 | } | ||
94 | |||
95 | #ifdef X86 | ||
96 | cmd += " -f "; | ||
97 | cmd += IPKG_CONF; | ||
98 | #endif | ||
99 | |||
100 | cmd += " " + option + " " + package + " 2>&1"; | ||
101 | |||
102 | qApp->processEvents(); | ||
103 | |||
104 | // If we are removing packages and make links option is selected | ||
105 | // create the links | ||
106 | if ( option == "remove" ) | ||
107 | { | ||
108 | createLinks = false; | ||
109 | if ( flags & MAKE_LINKS ) | ||
110 | { | ||
111 | emit outputText( QString( "Removing symbolic links...\n" ) ); | ||
112 | linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir ); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | emit outputText( cmd ); | ||
117 | |||
118 | // Execute command | ||
119 | dependantPackages = new QList<QString>; | ||
120 | dependantPackages->setAutoDelete( true ); | ||
121 | ret = executeIpkgCommand( cmd, option ); | ||
122 | |||
123 | if ( option == "install" ) | ||
124 | { | ||
125 | // If we are not removing packages and make links option is selected | ||
126 | // create the links | ||
127 | createLinks = true; | ||
128 | if ( flags & MAKE_LINKS ) | ||
129 | { | ||
130 | emit outputText( " " ); | ||
131 | emit outputText( QString( "Creating symbolic links for " )+ package ); | ||
132 | |||
133 | linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir ); | ||
134 | |||
135 | // link dependant packages that were installed with this release | ||
136 | QString *pkg; | ||
137 | for ( pkg = dependantPackages->first(); pkg != 0; pkg = dependantPackages->next() ) | ||
138 | { | ||
139 | emit outputText( " " ); | ||
140 | emit outputText( QString( "Creating symbolic links for " )+ (*pkg) ); | ||
141 | linkPackage( Utils::getPackageNameFromIpkFilename( *pkg ), destination, destDir ); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | delete dependantPackages; | ||
147 | |||
148 | emit outputText( QString( "Finished - status=" ) + (ret ? "success" : "failure") ); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | |||
153 | int Ipkg :: executeIpkgCommand( QString &cmd, const QString option ) | ||
154 | { | ||
155 | FILE *fp = NULL; | ||
156 | char line[130]; | ||
157 | QString lineStr, lineStrOld; | ||
158 | int ret = false; | ||
159 | |||
160 | fp = popen( (const char *) cmd, "r"); | ||
161 | if ( fp == NULL ) | ||
162 | { | ||
163 | cout << "Couldn't execute " << cmd << "! err = " << fp << endl; | ||
164 | QString text; | ||
165 | text.sprintf( "Couldn't execute %s! See stdout for error code", (const char *)cmd ); | ||
166 | emit outputText( text ); | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | while ( fgets( line, sizeof line, fp) != NULL ) | ||
171 | { | ||
172 | lineStr = line; | ||
173 | lineStr=lineStr.left( lineStr.length()-1 ); | ||
174 | |||
175 | if ( lineStr != lineStrOld ) | ||
176 | { | ||
177 | //See if we're finished | ||
178 | if ( option == "install" ) | ||
179 | { | ||
180 | // Need to keep track of any dependant packages that get installed | ||
181 | // so that we can create links to them as necessary | ||
182 | if ( lineStr.startsWith( "Installing " ) ) | ||
183 | { | ||
184 | cout << "LineStr = " << lineStr << endl; | ||
185 | int start = lineStr.find( " " ) + 1; | ||
186 | int end = lineStr.find( " ", start ); | ||
187 | QString *package = new QString( lineStr.mid( start, end-start ) ); | ||
188 | dependantPackages->append( package ); | ||
189 | cout << "installing dependant package <" << *package << ">" << endl; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if ( option == "update" ) | ||
194 | { | ||
195 | if (lineStr.contains("Updated list")) | ||
196 | ret = true; | ||
197 | } | ||
198 | else if ( option == "download" ) | ||
199 | { | ||
200 | if (lineStr.contains("Downloaded")) | ||
201 | ret = true; | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | if (lineStr.contains("Done")) | ||
206 | ret = true; | ||
207 | } | ||
208 | |||
209 | emit outputText( lineStr ); | ||
210 | } | ||
211 | lineStrOld = lineStr; | ||
212 | qApp->processEvents(); | ||
213 | } | ||
214 | pclose(fp); | ||
215 | } | ||
216 | |||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | |||
221 | void Ipkg :: linkPackage( const QString &packFileName, const QString &dest, const QString &destDir ) | ||
222 | { | ||
223 | if ( dest == "root" || dest == "/" ) | ||
224 | return; | ||
225 | |||
226 | qApp->processEvents(); | ||
227 | QStringList *fileList = getList( packFileName, destDir ); | ||
228 | qApp->processEvents(); | ||
229 | processFileList( fileList, destDir ); | ||
230 | delete fileList; | ||
231 | } | ||
232 | |||
233 | QStringList* Ipkg :: getList( const QString &packageFilename, const QString &destDir ) | ||
234 | { | ||
235 | QString packageFileDir = destDir+"/usr/lib/ipkg/info/"+packageFilename+".list"; | ||
236 | QFile f( packageFileDir ); | ||
237 | |||
238 | cout << "Try to open " << packageFileDir.latin1() << endl; | ||
239 | if ( !f.open(IO_ReadOnly) ) | ||
240 | { | ||
241 | // Couldn't open from dest, try from / | ||
242 | // cout << "Could not open:" << packageFileDir << endl; | ||
243 | f.close(); | ||
244 | |||
245 | packageFileDir = "/usr/lib/ipkg/info/"+packageFilename+".list"; | ||
246 | f.setName( packageFileDir ); | ||
247 | // cout << "Try to open " << packageFileDir.latin1() << endl; | ||
248 | if ( ! f.open(IO_ReadOnly) ) | ||
249 | { | ||
250 | cout << "Could not open:" << packageFileDir << endl; | ||
251 | emit outputText( QString( "Could not open :" ) + packageFileDir ); | ||
252 | return (QStringList*)0; | ||
253 | } | ||
254 | } | ||
255 | QStringList *fileList = new QStringList(); | ||
256 | QTextStream t( &f ); | ||
257 | while ( !t.eof() ) | ||
258 | *fileList += t.readLine(); | ||
259 | |||
260 | f.close(); | ||
261 | return fileList; | ||
262 | } | ||
263 | |||
264 | void Ipkg :: processFileList( const QStringList *fileList, const QString &destDir ) | ||
265 | { | ||
266 | if ( !fileList || fileList->isEmpty() ) | ||
267 | return; | ||
268 | |||
269 | QString baseDir = ROOT; | ||
270 | |||
271 | if ( createLinks == true ) | ||
272 | { | ||
273 | for ( uint i=0; i < fileList->count(); i++ ) | ||
274 | { | ||
275 | processLinkDir( (*fileList)[i], baseDir, destDir ); | ||
276 | qApp->processEvents(); | ||
277 | } | ||
278 | } | ||
279 | else | ||
280 | { | ||
281 | for ( int i = fileList->count()-1; i >= 0 ; i-- ) | ||
282 | { | ||
283 | cout << "i = " << i << ", Dealing with " << (*fileList)[i] << endl; | ||
284 | processLinkDir( (*fileList)[i], baseDir, destDir ); | ||
285 | qApp->processEvents(); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | void Ipkg :: processLinkDir( const QString &file, const QString &destDir, const QString &baseDir ) | ||
291 | { | ||
292 | QString sourceFile = baseDir + file; | ||
293 | QString linkFile = destDir + file; | ||
294 | QString text; | ||
295 | if ( createLinks ) | ||
296 | { | ||
297 | // If this file is a directory (ends with a /) and it doesn't exist, | ||
298 | // we need to create it | ||
299 | if ( file.right(1) == "/" ) | ||
300 | { | ||
301 | QFileInfo f( linkFile ); | ||
302 | if ( !f.exists() ) | ||
303 | { | ||
304 | emit outputText( QString( "Creating directory " ) + linkFile ); | ||
305 | QDir d; | ||
306 | d.mkdir( linkFile, true ); | ||
307 | } | ||
308 | else | ||
309 | emit outputText( QString( "Directory " ) + linkFile + " exists" ); | ||
310 | |||
311 | } | ||
312 | else | ||
313 | { | ||
314 | int rc = symlink( sourceFile, linkFile ); | ||
315 | text = (rc == 0 ? "Linked " : "Failed to link "); | ||
316 | text += sourceFile + " to " + linkFile; | ||
317 | emit outputText( text ); | ||
318 | } | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | QFileInfo f( linkFile ); | ||
323 | if ( f.exists() ) | ||
324 | { | ||
325 | if ( f.isFile() ) | ||
326 | { | ||
327 | QFile f( linkFile ); | ||
328 | bool rc = f.remove(); | ||
329 | |||
330 | text = (rc ? "Removed " : "Failed to remove "); | ||
331 | text += linkFile; | ||
332 | emit outputText( text ); | ||
333 | } | ||
334 | else if ( f.isDir() ) | ||
335 | { | ||
336 | QDir d; | ||
337 | bool rc = d.rmdir( linkFile, true ); | ||
338 | text = (rc ? "Removed " : "Failed to remove "); | ||
339 | text += linkFile; | ||
340 | emit outputText( text ); | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | |||
345 | } | ||