-rw-r--r-- | noncore/settings/aqpkg/ipkg.cpp | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/noncore/settings/aqpkg/ipkg.cpp b/noncore/settings/aqpkg/ipkg.cpp index dd9e78d..c5c6387 100644 --- a/noncore/settings/aqpkg/ipkg.cpp +++ b/noncore/settings/aqpkg/ipkg.cpp @@ -20,446 +20,453 @@ ++= -. .` .: : = ...= . :.=- You should have received a copy of the GNU -. .:....=;==+<; General Public License along with this file; -_. . . )=. = see the file COPYING. If not, write to the -- :-=` Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <opie2/oprocess.h> #ifdef QWS #include <qpe/qpeapplication.h> #else #include <qapplication.h> #endif #include <qdir.h> #include <qfile.h> #include <qtextstream.h> #include "utils.h" #include "ipkg.h" #include "global.h" using namespace Opie::Core; Ipkg :: Ipkg() { proc = 0; } 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 "") void Ipkg :: runIpkg() { error = false; QStringList commands; QDir::setCurrent( "/tmp" ); if ( runtimeDir != "" ) { commands << "cd "; commands << runtimeDir; commands << ";"; } commands << "ipkg" << "-V" << QString::number( infoLevel ) << "-force-defaults"; // only set the destination for an install operation if ( option == "install" ) commands << "-dest" << destination; if ( option != "update" && option != "download" ) { if ( flags & FORCE_DEPENDS ) commands << "-force-depends"; if ( flags & FORCE_REINSTALL ) commands << "-force-reinstall"; if ( flags & FORCE_REMOVE ) commands << "-force-removal-of-essential-packages"; if ( flags & FORCE_OVERWRITE ) commands << "-force-overwrite"; if ( infoLevel == 3 ) commands << "-verbose_wget"; // 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 commands << "-f"; commands << IPKG_CONF; #endif if ( option == "reinstall" ) commands << "install"; else commands << option; if ( package != "" ) commands << package; if ( package != "" ) emit outputText( tr( "Dealing with package %1" ).arg( package) ); qApp->processEvents(); // If we are removing, reinstalling or upgrading packages and make links option is selected // create the links if ( option == "remove" || option == "reinstall" || option == "upgrade" ) { createLinks = false; if ( flags & MAKE_LINKS ) { emit outputText( tr( "Removing symbolic links...\n" ) ); linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir ); emit outputText( QString( " " ) ); } } // Execute command dependantPackages = new QList<QString>; dependantPackages->setAutoDelete( true ); executeIpkgCommand( commands, option ); } void Ipkg :: createSymLinks() { if ( option == "install" || option == "reinstall" || option == "upgrade" ) { // 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( tr( "Creating symbolic links for %1." ).arg( 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( tr( "Creating symbolic links for %1" ).arg( *pkg ) ); linkPackage( Utils::getPackageNameFromIpkFilename( *pkg ), destination, destDir ); } } } delete dependantPackages; emit outputText( tr("Finished") ); emit outputText( "" ); } void Ipkg :: removeStatusEntry() { QString statusFile = destDir; if ( statusFile.right( 1 ) != "/" ) statusFile.append( "/" ); statusFile.append( "usr/lib/ipkg/status" ); QString outStatusFile = statusFile; outStatusFile.append( ".tmp" ); emit outputText( "" ); emit outputText( tr("Removing status entry...") ); QString tempstr = tr("status file - "); tempstr.append( statusFile ); emit outputText( tempstr ); tempstr = tr("package - "); tempstr.append( package ); emit outputText( tempstr ); QFile readFile( statusFile ); QFile writeFile( outStatusFile ); if ( !readFile.open( IO_ReadOnly ) ) { tempstr = tr("Couldn't open status file - "); tempstr.append( statusFile ); emit outputText( tempstr ); return; } if ( !writeFile.open( IO_WriteOnly ) ) { - tempstr = tr("Couldn't create tempory status file - "); + tempstr = tr("Couldn't create temporary status file - "); tempstr.append( outStatusFile ); emit outputText( tempstr ); return; } int i = 0; QTextStream readStream( &readFile ); QTextStream writeStream( &writeFile ); QString line; char k[21]; char v[1001]; QString key; QString value; while ( !readStream.atEnd() ) { //read new line line = readStream.readLine(); if ( line.contains( ":", TRUE ) ) { //grep key and value from line k[0] = '\0'; v[0] = '\0'; sscanf( line, "%[^:]: %[^\n]", k, v ); key = k; value = v; key = key.stripWhiteSpace(); value = value.stripWhiteSpace(); } else { key = ""; value = ""; } if ( key == "Package" && value == package ) { //skip lines from the deleted package while ( ( !readStream.atEnd() ) && ( line.stripWhiteSpace() != "" ) ) { line = readStream.readLine(); } } else { //write other lines into the tempfile writeStream << line << "\n"; // Improve UI responsiveness i++; if ( ( i % 50 ) == 0 ) qApp->processEvents(); } } readFile.close(); writeFile.close(); // Remove old status file and put tmp stats file in its place remove( statusFile ); - rename( outStatusFile, statusFile ); + if (::rename( outStatusFile, statusFile ) == -1) + { + tempstr = tr("Couldn't rename temporary status file - "); + tempstr.append( outStatusFile ); + tempstr.append( tr("to status file - ") ); + tempstr.append( statusFile ); + emit outputText( tempstr ); + } } int Ipkg :: executeIpkgLinkCommand( QStringList *cmd ) { // If one is already running - should never be but just to be safe if ( proc ) { delete proc; proc = 0; } // OK we're gonna use OProcess to run this thing proc = new OProcess(); aborted = false; // Connect up our slots connect(proc, SIGNAL(processExited(Opie::Core::OProcess*)), this, SLOT( linkProcessFinished())); connect(proc, SIGNAL(receivedStdout(Opie::Core::OProcess*,char*,int)), this, SLOT(linkCommandStdout(Opie::Core::OProcess*,char*,int))); *proc << *cmd; if(!proc->start(OProcess::NotifyOnExit, OProcess::All)) { emit outputText( tr("Couldn't start ipkg-link process" ) ); } return 0; } void Ipkg::linkProcessFinished() { // Report that the link process succeeded/failed if ( error ) emit outputText( tr("Symbolic linking failed!\n") ); else emit outputText( tr("Symbolic linking succeeded.\n") ); delete proc; proc = 0; finished = true; } void Ipkg::linkCommandStdout(OProcess*, char *buffer, int buflen) { QString lineStr = buffer; if ( lineStr[buflen-1] == '\n' ) buflen --; lineStr = lineStr.left( buflen ); emit outputText( lineStr ); if ( lineStr.find( " not found." ) != -1 ) { // Capture ipkg-link errors error = true; } buffer[0] = '\0'; } int Ipkg :: executeIpkgCommand( QStringList &cmd, const QString /*option*/ ) { // If one is already running - should never be but just to be safe if ( proc ) { delete proc; proc = 0; } // OK we're gonna use OProcess to run this thing proc = new OProcess(); aborted = false; // Connect up our slots connect(proc, SIGNAL(processExited(Opie::Core::OProcess*)), this, SLOT( processFinished())); connect(proc, SIGNAL(receivedStdout(Opie::Core::OProcess*,char*,int)), this, SLOT(commandStdout(Opie::Core::OProcess*,char*,int))); connect(proc, SIGNAL(receivedStderr(Opie::Core::OProcess*,char*,int)), this, SLOT(commandStderr(Opie::Core::OProcess*,char*,int))); for ( QStringList::Iterator it = cmd.begin(); it != cmd.end(); ++it ) { *proc << (*it).latin1(); } // Start the process going finished = false; if(!proc->start(OProcess::NotifyOnExit, OProcess::All)) { emit outputText( tr("Couldn't start ipkg process" ) ); } return 0; } void Ipkg::commandStdout(OProcess*, char *buffer, int buflen) { QString lineStr = buffer; if ( lineStr[buflen-1] == '\n' ) buflen --; lineStr = lineStr.left( buflen ); emit outputText( lineStr ); // check if we are installing dependant packages 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 " ) ) { int start = lineStr.find( " " ) + 1; int end = lineStr.find( " ", start ); QString *package = new QString( lineStr.mid( start, end-start ) ); dependantPackages->append( package ); } } else if ( option == "remove" && !( flags & FORCE_DEPENDS ) && lineStr.find( "is depended upon by packages:" ) != -1 ) { // Ipkg should send this to STDERR, but doesn't - so trap here error = true; } buffer[0] = '\0'; } void Ipkg::commandStderr(OProcess*, char *buffer, int buflen) { QString lineStr = buffer; if ( lineStr[buflen-1] == '\n' ) buflen --; lineStr=lineStr.left( buflen ); emit outputText( lineStr ); buffer[0] = '\0'; error = true; } void Ipkg::processFinished() { // 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 ( !error && option == "remove" ) removeStatusEntry(); delete proc; proc = 0; finished = true; emit ipkgFinished(); } void Ipkg :: abort() { if ( proc ) { proc->kill(); aborted = true; } } void Ipkg :: linkPackage( const QString &packFileName, const QString &dest, const QString &destDir ) { Q_CONST_UNUSED( destDir ) if ( dest == "root" || dest == "/" ) return; if( option == "remove" || option == "reinstall" || option == "upgrade" ) { QStringList commands; if ( runtimeDir != "" ) { commands << "cd "; commands << runtimeDir; commands << ";"; } commands << "ipkg-link" << "remove" << packFileName; executeIpkgLinkCommand( &commands ); } if( option == "install" || option == "reinstall" || option == "upgrade" ) { QStringList commands; if ( runtimeDir != "" ) |