summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/aqpkg/ipkg.cpp82
-rw-r--r--noncore/settings/aqpkg/ipkg.h1
2 files changed, 81 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
@@ -35,68 +35,72 @@ using namespace std;
Ipkg :: Ipkg()
{
}
Ipkg :: ~Ipkg()
{
}
// Option is what we are going to do - install, upgrade, download, reinstall
// package is the package name to install - either a fully qualified path and ipk
// file (if stored locally) or just the name of the package (for a network package)
// packageName is the package name - (for a network package this will be the same as
// package parameter)
// dest is the destination alias (from ipk.conf)
// destDir is the dir that the destination alias points to (used to link to root)
// flags is the ipkg options flags
// dir is the directory to run ipkg in (defaults to "")
bool Ipkg :: runIpkg( )
{
bool ret = false;
QDir::setCurrent( "/tmp" );
QString cmd = "";
if ( runtimeDir != "" )
{
cmd += "cd ";
cmd += runtimeDir;
cmd += " ; ";
}
cmd += "ipkg -force-defaults";
- if ( option != "update" && option != "download" )
- {
+
+ // only set the destination for an install operation
+ if ( option == "install" )
cmd += " -dest "+ destination;
+
+ if ( option != "update" && option != "download" )
+ {
if ( flags & FORCE_DEPENDS )
cmd += " -force-depends";
if ( flags & FORCE_REINSTALL )
cmd += " -force-reinstall";
if ( flags & FORCE_REMOVE )
cmd += " -force-removal-of-essential-packages";
if ( flags & FORCE_OVERWRITE )
cmd += " -force-overwrite";
// Handle make links
// Rules - If make links is switched on, create links to root
// if destDir is NOT /
if ( flags & MAKE_LINKS )
{
// If destDir == / turn off make links as package is being insalled
// to root already.
if ( destDir == "/" )
flags ^= MAKE_LINKS;
}
}
#ifdef X86
cmd += " -f ";
cmd += IPKG_CONF;
#endif
if ( option == "reinstall" )
cmd += " install";
else
cmd += " " + option;
if ( package != "" )
@@ -127,71 +131,145 @@ bool Ipkg :: runIpkg( )
// Execute command
dependantPackages = new QList<QString>;
dependantPackages->setAutoDelete( true );
ret = executeIpkgCommand( cmd, option );
if ( option == "install" || option == "reinstall" )
{
// If we are not removing packages and make links option is selected
// create the links
createLinks = true;
if ( flags & MAKE_LINKS )
{
emit outputText( " " );
emit outputText( QString( "Creating symbolic links for " )+ package );
linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir );
// link dependant packages that were installed with this release
QString *pkg;
for ( pkg = dependantPackages->first(); pkg != 0; pkg = dependantPackages->next() )
{
if ( *pkg == package )
continue;
emit outputText( " " );
emit outputText( QString( "Creating symbolic links for " )+ (*pkg) );
linkPackage( Utils::getPackageNameFromIpkFilename( *pkg ), destination, destDir );
}
}
}
delete dependantPackages;
+
+ // Finally, if we are removing a package, remove its entry from the <destdir>/usr/lib/ipkg/status file
+ // to workaround an ipkg bug which stops reinstall to a different location
+ if ( option == "remove" )
+ removeStatusEntry();
+
// emit outputText( QString( "Finished - status=" ) + (ret ? "success" : "failure") );
emit outputText( "Finished" );
emit outputText( "" );
return ret;
}
+void Ipkg :: removeStatusEntry()
+{
+ QString statusFile = destDir;
+ if ( statusFile.right( 1 ) != "/" )
+ statusFile += "/";
+ statusFile += "usr/lib/ipkg/status";
+ QString outStatusFile = statusFile + ".tmp";
+
+ emit outputText( "" );
+ emit outputText( "Removing status entry..." );
+ emit outputText( QString( "status file - " )+ statusFile );
+ emit outputText( QString( "package - " )+ package );
+
+ ifstream in( statusFile );
+ ofstream out( outStatusFile );
+ if ( !in.is_open() )
+ {
+ emit outputText( QString( "Couldn't open status file - " )+ statusFile );
+ return;
+ }
+
+ if ( !out.is_open() )
+ {
+ emit outputText( QString( "Couldn't create tempory status file - " )+ outStatusFile );
+ return;
+ }
+
+ char line[1001];
+ char k[21];
+ char v[1001];
+ QString key;
+ QString value;
+ do
+ {
+ in.getline( line, 1000 );
+ if ( in.eof() )
+ continue;
+
+ k[0] = '\0';
+ v[0] = '\0';
+
+ sscanf( line, "%[^:]: %[^\n]", k, v );
+ key = k;
+ value = v;
+ key = key.stripWhiteSpace();
+ value = value.stripWhiteSpace();
+ if ( key == "Package" && value == package )
+ {
+ // Ignore all lines up to next empty
+ do
+ {
+ in.getline( line, 1000 );
+ if ( in.eof() || QString( line ).stripWhiteSpace() == "" )
+ continue;
+ } while ( !in.eof() && QString( line ).stripWhiteSpace() != "" );
+ }
+
+ out << line << endl;
+ } while ( !in.eof() );
+
+ in.close();
+ out.close();
+
+ // Remove old status file and put tmp stats file in its place
+ remove( statusFile );
+ rename( outStatusFile, statusFile );
+}
+
int Ipkg :: executeIpkgCommand( QString &cmd, const QString option )
{
FILE *fp = NULL;
char line[130];
QString lineStr, lineStrOld;
int ret = false;
fp = popen( (const char *) cmd, "r");
if ( fp == NULL )
{
cout << "Couldn't execute " << cmd << "! err = " << fp << endl;
QString text;
text.sprintf( "Couldn't execute %s! See stdout for error code", (const char *)cmd );
emit outputText( text );
}
else
{
while ( fgets( line, sizeof line, fp) != NULL )
{
lineStr = line;
lineStr=lineStr.left( lineStr.length()-1 );
if ( lineStr != lineStrOld )
{
//See if we're finished
if ( option == "install" || option == "reinstall" )
{
// Need to keep track of any dependant packages that get installed
// so that we can create links to them as necessary
if ( lineStr.startsWith( "Installing " ) )
{
diff --git a/noncore/settings/aqpkg/ipkg.h b/noncore/settings/aqpkg/ipkg.h
index 63588c4..55e9ff4 100644
--- a/noncore/settings/aqpkg/ipkg.h
+++ b/noncore/settings/aqpkg/ipkg.h
@@ -34,39 +34,40 @@
#define MAKE_LINKS 0x0010
class Ipkg : public QObject
{
Q_OBJECT
public:
Ipkg();
~Ipkg();
bool runIpkg( );
void setOption( const char *opt ) { option = opt; }
void setPackage( const char *pkg ) { package = pkg; }
void setDestination( const char *dest ) { destination = dest; }
void setDestinationDir( const char *dir ) { destDir = dir; }
void setFlags( int fl ) { flags = fl; }
void setRuntimeDirectory( const char *dir ) { runtimeDir = dir; }
signals:
void outputText( const QString &text );
private:
bool createLinks;
QString option;
QString package;
QString destination;
QString destDir;
int flags;
QString runtimeDir;
QList<QString> *dependantPackages;
int executeIpkgCommand( QString &cmd, const QString option );
+ void removeStatusEntry();
void linkPackage( const QString &packFileName, const QString &dest, const QString &destDir );
QStringList* getList( const QString &packageFilename, const QString &destDir );
void processFileList( const QStringList *fileList, const QString &destDir );
void processLinkDir( const QString &file, const QString &baseDir, const QString &destDir );
};
#endif