summaryrefslogtreecommitdiff
path: root/noncore/settings/aqpkg/ipkg.cpp
Unidiff
Diffstat (limited to 'noncore/settings/aqpkg/ipkg.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/aqpkg/ipkg.cpp82
1 files changed, 80 insertions, 2 deletions
diff --git a/noncore/settings/aqpkg/ipkg.cpp b/noncore/settings/aqpkg/ipkg.cpp
index c762633..452eca3 100644
--- a/noncore/settings/aqpkg/ipkg.cpp
+++ b/noncore/settings/aqpkg/ipkg.cpp
@@ -19,195 +19,273 @@
19using namespace std; 19using namespace std;
20 20
21#include <stdio.h> 21#include <stdio.h>
22#include <unistd.h> 22#include <unistd.h>
23 23
24#ifdef QWS 24#ifdef QWS
25#include <qpe/qpeapplication.h> 25#include <qpe/qpeapplication.h>
26#else 26#else
27#include <qapplication.h> 27#include <qapplication.h>
28#endif 28#endif
29#include <qdir.h> 29#include <qdir.h>
30#include <qtextstream.h> 30#include <qtextstream.h>
31 31
32#include "utils.h" 32#include "utils.h"
33#include "ipkg.h" 33#include "ipkg.h"
34#include "global.h" 34#include "global.h"
35 35
36Ipkg :: Ipkg() 36Ipkg :: Ipkg()
37{ 37{
38} 38}
39 39
40Ipkg :: ~Ipkg() 40Ipkg :: ~Ipkg()
41{ 41{
42} 42}
43 43
44// Option is what we are going to do - install, upgrade, download, reinstall 44// Option is what we are going to do - install, upgrade, download, reinstall
45// package is the package name to install - either a fully qualified path and ipk 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) 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 47// packageName is the package name - (for a network package this will be the same as
48// package parameter) 48// package parameter)
49// dest is the destination alias (from ipk.conf) 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) 50// destDir is the dir that the destination alias points to (used to link to root)
51// flags is the ipkg options flags 51// flags is the ipkg options flags
52// dir is the directory to run ipkg in (defaults to "") 52// dir is the directory to run ipkg in (defaults to "")
53bool Ipkg :: runIpkg( ) 53bool Ipkg :: runIpkg( )
54{ 54{
55 bool ret = false; 55 bool ret = false;
56 56
57 QDir::setCurrent( "/tmp" ); 57 QDir::setCurrent( "/tmp" );
58 QString cmd = ""; 58 QString cmd = "";
59 59
60 if ( runtimeDir != "" ) 60 if ( runtimeDir != "" )
61 { 61 {
62 cmd += "cd "; 62 cmd += "cd ";
63 cmd += runtimeDir; 63 cmd += runtimeDir;
64 cmd += " ; "; 64 cmd += " ; ";
65 } 65 }
66 cmd += "ipkg -force-defaults"; 66 cmd += "ipkg -force-defaults";
67 if ( option != "update" && option != "download" ) 67
68 { 68 // only set the destination for an install operation
69 if ( option == "install" )
69 cmd += " -dest "+ destination; 70 cmd += " -dest "+ destination;
70 71
72
73 if ( option != "update" && option != "download" )
74 {
71 if ( flags & FORCE_DEPENDS ) 75 if ( flags & FORCE_DEPENDS )
72 cmd += " -force-depends"; 76 cmd += " -force-depends";
73 if ( flags & FORCE_REINSTALL ) 77 if ( flags & FORCE_REINSTALL )
74 cmd += " -force-reinstall"; 78 cmd += " -force-reinstall";
75 if ( flags & FORCE_REMOVE ) 79 if ( flags & FORCE_REMOVE )
76 cmd += " -force-removal-of-essential-packages"; 80 cmd += " -force-removal-of-essential-packages";
77 if ( flags & FORCE_OVERWRITE ) 81 if ( flags & FORCE_OVERWRITE )
78 cmd += " -force-overwrite"; 82 cmd += " -force-overwrite";
79 83
80 // Handle make links 84 // Handle make links
81 // Rules - If make links is switched on, create links to root 85 // Rules - If make links is switched on, create links to root
82 // if destDir is NOT / 86 // if destDir is NOT /
83 if ( flags & MAKE_LINKS ) 87 if ( flags & MAKE_LINKS )
84 { 88 {
85 // If destDir == / turn off make links as package is being insalled 89 // If destDir == / turn off make links as package is being insalled
86 // to root already. 90 // to root already.
87 if ( destDir == "/" ) 91 if ( destDir == "/" )
88 flags ^= MAKE_LINKS; 92 flags ^= MAKE_LINKS;
89 } 93 }
90 } 94 }
91 95
92#ifdef X86 96#ifdef X86
93 cmd += " -f "; 97 cmd += " -f ";
94 cmd += IPKG_CONF; 98 cmd += IPKG_CONF;
95#endif 99#endif
96 100
97 101
98 if ( option == "reinstall" ) 102 if ( option == "reinstall" )
99 cmd += " install"; 103 cmd += " install";
100 else 104 else
101 cmd += " " + option; 105 cmd += " " + option;
102 if ( package != "" ) 106 if ( package != "" )
103 cmd += " " + package; 107 cmd += " " + package;
104 cmd += " 2>&1"; 108 cmd += " 2>&1";
105 109
106 110
107 if ( package != "" ) 111 if ( package != "" )
108 emit outputText( QString( "Dealing with package " ) + package ); 112 emit outputText( QString( "Dealing with package " ) + package );
109 113
110 qApp->processEvents(); 114 qApp->processEvents();
111 115
112 // If we are removing packages and make links option is selected 116 // If we are removing packages and make links option is selected
113 // create the links 117 // create the links
114 if ( option == "remove" || option == "reinstall" ) 118 if ( option == "remove" || option == "reinstall" )
115 { 119 {
116 createLinks = false; 120 createLinks = false;
117 if ( flags & MAKE_LINKS ) 121 if ( flags & MAKE_LINKS )
118 { 122 {
119 emit outputText( QString( "Removing symbolic links...\n" ) ); 123 emit outputText( QString( "Removing symbolic links...\n" ) );
120 linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir ); 124 linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir );
121 emit outputText( QString( " " ) ); 125 emit outputText( QString( " " ) );
122 } 126 }
123 } 127 }
124 128
125 emit outputText( cmd ); 129 emit outputText( cmd );
126 130
127 // Execute command 131 // Execute command
128 dependantPackages = new QList<QString>; 132 dependantPackages = new QList<QString>;
129 dependantPackages->setAutoDelete( true ); 133 dependantPackages->setAutoDelete( true );
130 134
131 ret = executeIpkgCommand( cmd, option ); 135 ret = executeIpkgCommand( cmd, option );
132 136
133 if ( option == "install" || option == "reinstall" ) 137 if ( option == "install" || option == "reinstall" )
134 { 138 {
135 // If we are not removing packages and make links option is selected 139 // If we are not removing packages and make links option is selected
136 // create the links 140 // create the links
137 createLinks = true; 141 createLinks = true;
138 if ( flags & MAKE_LINKS ) 142 if ( flags & MAKE_LINKS )
139 { 143 {
140 emit outputText( " " ); 144 emit outputText( " " );
141 emit outputText( QString( "Creating symbolic links for " )+ package ); 145 emit outputText( QString( "Creating symbolic links for " )+ package );
142 146
143 linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir ); 147 linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir );
144 148
145 // link dependant packages that were installed with this release 149 // link dependant packages that were installed with this release
146 QString *pkg; 150 QString *pkg;
147 for ( pkg = dependantPackages->first(); pkg != 0; pkg = dependantPackages->next() ) 151 for ( pkg = dependantPackages->first(); pkg != 0; pkg = dependantPackages->next() )
148 { 152 {
149 if ( *pkg == package ) 153 if ( *pkg == package )
150 continue; 154 continue;
151 emit outputText( " " ); 155 emit outputText( " " );
152 emit outputText( QString( "Creating symbolic links for " )+ (*pkg) ); 156 emit outputText( QString( "Creating symbolic links for " )+ (*pkg) );
153 linkPackage( Utils::getPackageNameFromIpkFilename( *pkg ), destination, destDir ); 157 linkPackage( Utils::getPackageNameFromIpkFilename( *pkg ), destination, destDir );
154 } 158 }
155 } 159 }
156 } 160 }
157 161
158 delete dependantPackages; 162 delete dependantPackages;
163
164 // Finally, if we are removing a package, remove its entry from the <destdir>/usr/lib/ipkg/status file
165 // to workaround an ipkg bug which stops reinstall to a different location
166 if ( option == "remove" )
167 removeStatusEntry();
159 168
169
160// emit outputText( QString( "Finished - status=" ) + (ret ? "success" : "failure") ); 170// emit outputText( QString( "Finished - status=" ) + (ret ? "success" : "failure") );
161 emit outputText( "Finished" ); 171 emit outputText( "Finished" );
162 emit outputText( "" ); 172 emit outputText( "" );
163 return ret; 173 return ret;
164} 174}
165 175
176void Ipkg :: removeStatusEntry()
177{
178 QString statusFile = destDir;
179 if ( statusFile.right( 1 ) != "/" )
180 statusFile += "/";
181 statusFile += "usr/lib/ipkg/status";
182 QString outStatusFile = statusFile + ".tmp";
183
184 emit outputText( "" );
185 emit outputText( "Removing status entry..." );
186 emit outputText( QString( "status file - " )+ statusFile );
187 emit outputText( QString( "package - " )+ package );
188
189 ifstream in( statusFile );
190 ofstream out( outStatusFile );
191 if ( !in.is_open() )
192 {
193 emit outputText( QString( "Couldn't open status file - " )+ statusFile );
194 return;
195 }
196
197 if ( !out.is_open() )
198 {
199 emit outputText( QString( "Couldn't create tempory status file - " )+ outStatusFile );
200 return;
201 }
202
203 char line[1001];
204 char k[21];
205 char v[1001];
206 QString key;
207 QString value;
208 do
209 {
210 in.getline( line, 1000 );
211 if ( in.eof() )
212 continue;
213
214 k[0] = '\0';
215 v[0] = '\0';
216
217 sscanf( line, "%[^:]: %[^\n]", k, v );
218 key = k;
219 value = v;
220 key = key.stripWhiteSpace();
221 value = value.stripWhiteSpace();
222 if ( key == "Package" && value == package )
223 {
224 // Ignore all lines up to next empty
225 do
226 {
227 in.getline( line, 1000 );
228 if ( in.eof() || QString( line ).stripWhiteSpace() == "" )
229 continue;
230 } while ( !in.eof() && QString( line ).stripWhiteSpace() != "" );
231 }
232
233 out << line << endl;
234 } while ( !in.eof() );
235
236 in.close();
237 out.close();
238
239 // Remove old status file and put tmp stats file in its place
240 remove( statusFile );
241 rename( outStatusFile, statusFile );
242}
243
166 244
167int Ipkg :: executeIpkgCommand( QString &cmd, const QString option ) 245int Ipkg :: executeIpkgCommand( QString &cmd, const QString option )
168{ 246{
169 FILE *fp = NULL; 247 FILE *fp = NULL;
170 char line[130]; 248 char line[130];
171 QString lineStr, lineStrOld; 249 QString lineStr, lineStrOld;
172 int ret = false; 250 int ret = false;
173 251
174 fp = popen( (const char *) cmd, "r"); 252 fp = popen( (const char *) cmd, "r");
175 if ( fp == NULL ) 253 if ( fp == NULL )
176 { 254 {
177 cout << "Couldn't execute " << cmd << "! err = " << fp << endl; 255 cout << "Couldn't execute " << cmd << "! err = " << fp << endl;
178 QString text; 256 QString text;
179 text.sprintf( "Couldn't execute %s! See stdout for error code", (const char *)cmd ); 257 text.sprintf( "Couldn't execute %s! See stdout for error code", (const char *)cmd );
180 emit outputText( text ); 258 emit outputText( text );
181 } 259 }
182 else 260 else
183 { 261 {
184 while ( fgets( line, sizeof line, fp) != NULL ) 262 while ( fgets( line, sizeof line, fp) != NULL )
185 { 263 {
186 lineStr = line; 264 lineStr = line;
187 lineStr=lineStr.left( lineStr.length()-1 ); 265 lineStr=lineStr.left( lineStr.length()-1 );
188 266
189 if ( lineStr != lineStrOld ) 267 if ( lineStr != lineStrOld )
190 { 268 {
191 //See if we're finished 269 //See if we're finished
192 if ( option == "install" || option == "reinstall" ) 270 if ( option == "install" || option == "reinstall" )
193 { 271 {
194 // Need to keep track of any dependant packages that get installed 272 // Need to keep track of any dependant packages that get installed
195 // so that we can create links to them as necessary 273 // so that we can create links to them as necessary
196 if ( lineStr.startsWith( "Installing " ) ) 274 if ( lineStr.startsWith( "Installing " ) )
197 { 275 {
198 int start = lineStr.find( " " ) + 1; 276 int start = lineStr.find( " " ) + 1;
199 int end = lineStr.find( " ", start ); 277 int end = lineStr.find( " ", start );
200 QString *package = new QString( lineStr.mid( start, end-start ) ); 278 QString *package = new QString( lineStr.mid( start, end-start ) );
201 dependantPackages->append( package ); 279 dependantPackages->append( package );
202 } 280 }
203 } 281 }
204 282
205 if ( option == "update" ) 283 if ( option == "update" )
206 { 284 {
207 if (lineStr.contains("Updated list")) 285 if (lineStr.contains("Updated list"))
208 ret = true; 286 ret = true;
209 } 287 }
210 else if ( option == "download" ) 288 else if ( option == "download" )
211 { 289 {
212 if (lineStr.contains("Downloaded")) 290 if (lineStr.contains("Downloaded"))
213 ret = true; 291 ret = true;