-rw-r--r-- | noncore/settings/packagemanager/ChangeLog | 7 | ||||
-rw-r--r-- | noncore/settings/packagemanager/TODO | 8 | ||||
-rw-r--r-- | noncore/settings/packagemanager/installdlg.cpp | 81 | ||||
-rw-r--r-- | noncore/settings/packagemanager/installdlg.h | 11 | ||||
-rw-r--r-- | noncore/settings/packagemanager/oipkg.cpp | 208 | ||||
-rw-r--r-- | noncore/settings/packagemanager/oipkg.h | 20 | ||||
-rw-r--r-- | noncore/settings/packagemanager/oipkgconfigdlg.cpp | 34 | ||||
-rw-r--r-- | noncore/settings/packagemanager/oipkgconfigdlg.h | 3 | ||||
-rw-r--r-- | noncore/settings/packagemanager/opackagemanager.cpp | 20 | ||||
-rw-r--r-- | noncore/settings/packagemanager/opie-packagemanager.control | 4 | ||||
-rw-r--r-- | noncore/settings/packagemanager/packageinfodlg.cpp | 10 | ||||
-rw-r--r-- | noncore/settings/packagemanager/packageinfodlg.h | 4 |
12 files changed, 237 insertions, 173 deletions
diff --git a/noncore/settings/packagemanager/ChangeLog b/noncore/settings/packagemanager/ChangeLog index c776ce5..608cd98 100644 --- a/noncore/settings/packagemanager/ChangeLog +++ b/noncore/settings/packagemanager/ChangeLog @@ -1,24 +1,31 @@ +2005-01-02 Dan Williams <drw@handhelds.org> + + * Released version 0.6.1 + * Implemented native package linking code to remove need for ipkg-link + * Implement package in OIpkg (removed from InstallDlg) as this is ipkg specific + * Many small code tweaks + 2004-12-21 Dan Williams <drw@handhelds.org> * Released version 0.6.0 * Added support for Ipkg 'src/gz' feeds * Improve server and destination tabs UI's in configuration dialog * Fix app linking to link all dependent packages as well as selected packages * Hide 'Retrive File List' button once list is retrieved in Package Info dialog 2004-11-18 Dan Williams <drw@handhelds.org> * Released version 0.5.0 * All v1.0 functionality implemented * Implemented installation of local packages * Implemented linking of non-root apps (using ipkg-link) * Many UI tweaks for installation and filter dialogs 2004-04-21 Dan Williams <drw@handhelds.org> * Released version 0.4.0 * Added saving of ipkg configuration information * Re-initialize ipkg when configuration information changes * Added QWhatsThis for all UI controls * Remove Location from OConfItem as it is not used/needed * Re-ordered includes to follow Opie standards diff --git a/noncore/settings/packagemanager/TODO b/noncore/settings/packagemanager/TODO index 744ad95..2512624 100644 --- a/noncore/settings/packagemanager/TODO +++ b/noncore/settings/packagemanager/TODO @@ -1,17 +1,15 @@ /************************************************************************ /* /* Opie - Package Manager /* ======================== -/* Version 0.6.0 +/* Version 0.6.1 /* /* A package management client for Opie /* /************************************************************************ ----------------------------------------------- - To-do for Opie-PackageManager - December, 2004 + To-do for Opie-PackageManager - January, 2005 ----------------------------------------------- -1. Move ipkg-link code from InstallDlg to OIpkg -2. Code ipkg-link logic directly in OIpkg -3. Re-work package download dialog +1. Re-work package download dialog diff --git a/noncore/settings/packagemanager/installdlg.cpp b/noncore/settings/packagemanager/installdlg.cpp index 985e2bd..7dea591 100644 --- a/noncore/settings/packagemanager/installdlg.cpp +++ b/noncore/settings/packagemanager/installdlg.cpp @@ -9,49 +9,48 @@ _;:, .> :=|. This file is free software; you can :`=1 )Y*s>-.-- : the terms of the GNU General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This file is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU General ..}^=.= = ; Public License for more details. ++= -. .` .: : = ...= . :.=- 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 "installdlg.h" #include <opie2/ofiledialog.h> -#include <opie2/oprocess.h> #include <qpe/fileselector.h> #include <qpe/resource.h> #include <qpe/storage.h> #include <qapplication.h> #include <qcombobox.h> #include <qfileinfo.h> #include <qgroupbox.h> #include <qlabel.h> #include <qlayout.h> #include <qmap.h> #include <qmultilineedit.h> #include <qpushbutton.h> #include <sys/vfs.h> #include "opackagemanager.h" InstallDlg::InstallDlg( QWidget *parent, OPackageManager *pm, const QString &caption, OPackage::Command command1, const QStringList &packages1, OPackage::Command command2, const QStringList &packages2, OPackage::Command command3, const QStringList &packages3 ) : QWidget( 0l ) @@ -226,163 +225,87 @@ void InstallDlg::slotBtnStart() // TODO - force reload of package data emit closeInstallDlg(); return; } // Start was clicked, start executing QString dest; if ( m_installFound ) { dest = m_destination->currentText(); m_destination->setEnabled( false ); } m_btnOptions->setEnabled( false ); if ( m_numCommands > 1 ) { m_btnStart->setText( tr( "Abort" ) ); m_btnStart->setIconSet( Resource::loadPixmap( "close" ) ); } else { m_btnStart->setEnabled( false ); } - Opie::Core::OProcess process( this ); for ( m_currCommand = 0; m_currCommand < m_numCommands; m_currCommand++ ) { // Execute next command m_packman->executeCommand( m_command[ m_currCommand ], m_packages[ m_currCommand ], dest, - this, SLOT(slotOutput(char*)), true ); - - if ( m_command[ m_currCommand ] == OPackage::Remove ) - { - // Unlink application if the package was removed - - // Loop through all package names in the command group - for ( QStringList::Iterator it = m_packages[ m_currCommand ].begin(); - it != m_packages[ m_currCommand ].end(); - ++it ) - { - OPackage *currPackage = m_packman->findPackage( (*it) ); - - // Skip package if it is not found or being removed from 'root' - if ( !currPackage || ( m_command[ m_currCommand ] == OPackage::Remove && - currPackage->destination() == "root" ) ) - continue; - - // Display feedback to user - m_output->append( tr( QString( "Running ipkg-link to remove links for package '%1'." ) - .arg( currPackage->name() ) ) ); - m_output->setCursorPosition( m_output->numLines(), 0 ); - - // Execute ipkg-link - process.clearArguments(); - process << "ipkg-link" - << ( ( m_command[ m_currCommand ] == OPackage::Install ) ? "add" : "remove" ) - << currPackage->name(); - if ( !process.start( Opie::Core::OProcess::Block, - Opie::Core::OProcess::NoCommunication ) ) - { - slotProcessDone( 0l ); - m_output->append( tr( "Unable to run ipkg-link." ) ); - m_output->setCursorPosition( m_output->numLines(), 0 ); - return; - } - } - } - else if ( m_command[ m_currCommand ] == OPackage::Install && dest != "root" ) - { - // Link applications in the destination directory - - m_output->append( tr( "Running ipkg-link to link packages in '%1'." ).arg( dest ) ); - m_output->setCursorPosition( m_output->numLines(), 0 ); - - QString destPath; - OConfItem *destItem = m_packman->findConfItem( OConfItem::Destination, dest ); - - // Execute ipkg-link - process.clearArguments(); - process << "ipkg-link" - << "mount" - << destItem->value(); - if ( !process.start( Opie::Core::OProcess::Block, - Opie::Core::OProcess::NoCommunication ) ) - { - slotProcessDone( 0l ); - m_output->append( tr( "Unable to run ipkg-link." ) ); - m_output->setCursorPosition( m_output->numLines(), 0 ); - return; - } - } - } - - slotProcessDone( 0l ); -} - -void InstallDlg::slotProcessDone( Opie::Core::OProcess *proc ) -{ - if ( proc ) - { - // Display message pnly if linking was done - m_output->append( tr( "The package linking is done." ) ); - m_output->setCursorPosition( m_output->numLines(), 0 ); - - delete proc; + this, SLOT(slotOutput(const QString &)), true ); } // All commands executed, allow user to close dialog m_btnStart->setEnabled( true ); m_btnStart->setText( tr( "Close" ) ); m_btnStart->setIconSet( Resource::loadPixmap( "enter" ) ); m_btnOptions->setEnabled( true ); m_btnOptions->setText( tr( "Save output" ) ); m_btnOptions->setIconSet( Resource::loadPixmap( "save" ) ); } void InstallDlg::slotBtnOptions() { QString btnText = m_btnOptions->text(); if ( btnText == tr( "Options" ) ) { // Display configuration dialog (only options tab is enabled) m_packman->configureDlg( true ); return; } // Save output was clicked QMap<QString, QStringList> map; map.insert( tr( "All" ), QStringList() ); QStringList text; text << "text/*"; map.insert(tr( "Text" ), text ); text << "*"; map.insert( tr( "All" ), text ); QString filename = Opie::Ui::OFileDialog::getSaveFileName( 2, "/", "ipkg-output", map ); if( !filename.isEmpty() ) { QString currentFileName = QFileInfo( filename ).fileName(); DocLnk doc; doc.setType( "text/plain" ); doc.setFile( filename ); doc.setName( currentFileName ); FileManager fm; fm.saveFile( doc, m_output->text() ); } } -void InstallDlg::slotOutput( char *msg ) +void InstallDlg::slotOutput( const QString &msg ) { // Allow processing of other events qApp->processEvents(); QString lineStr = msg; if ( lineStr[lineStr.length()-1] == '\n' ) lineStr.truncate( lineStr.length() - 1 ); m_output->append( lineStr ); m_output->setCursorPosition( m_output->numLines(), 0 ); // Update available space slotDisplayAvailSpace( QString::null ); } diff --git a/noncore/settings/packagemanager/installdlg.h b/noncore/settings/packagemanager/installdlg.h index 7a64fe0..e633809 100644 --- a/noncore/settings/packagemanager/installdlg.h +++ b/noncore/settings/packagemanager/installdlg.h @@ -21,81 +21,72 @@ _;:, .> :=|. This file is free software; you can : = ...= . :.=- 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. */ #ifndef INSTALLDLG_H #define INSTALLDLG_H #include <qwidget.h> #include "opackage.h" class QComboBox; class QLabel; class QMultiLineEdit; class QPushButton; class OConfItem; class OPackageManager; -namespace Opie -{ - namespace Core - { - class OProcess; - } -} - class InstallDlg : public QWidget { Q_OBJECT public: InstallDlg( QWidget *parent = 0l, OPackageManager *pm = 0l, const QString &caption = QString::null, OPackage::Command command1 = OPackage::NotDefined, const QStringList &packages1 = QStringList(), OPackage::Command command2 = OPackage::NotDefined, const QStringList &packages2 = QStringList(), OPackage::Command command3 = OPackage::NotDefined, const QStringList &packages3 = QStringList() ); private: OPackageManager *m_packman; // Pointer to application instance of package manager bool m_installFound; // Indicates if an install is being done, controls display of // destination selection, available space // UI controls QComboBox *m_destination; // Destination selection list QLabel *m_availSpace; // Text label to display available space on selected destination QMultiLineEdit *m_output; // Multi-line edit to display status QPushButton *m_btnStart; // Start/abort/close button QPushButton *m_btnOptions; // Installation options button // Commands and packages to execute int m_numCommands; // Number of commands to be executed int m_currCommand; // Number of currently executing command OPackage::Command m_command[3]; // List of commands to be executed QStringList m_packages[3]; // Lists of package names associated to commands (m_command[]) OConfItem *m_destItem; // Pointer to destination for package installation private slots: // UI control slots void slotDisplayAvailSpace( const QString &destination ); void slotBtnStart(); void slotBtnOptions(); - void slotProcessDone( Opie::Core::OProcess *proc ); // Execution slots - void slotOutput( char *msg ); + void slotOutput( const QString &msg ); signals: void closeInstallDlg(); }; #endif diff --git a/noncore/settings/packagemanager/oipkg.cpp b/noncore/settings/packagemanager/oipkg.cpp index a66bd51..f2d7e39 100644 --- a/noncore/settings/packagemanager/oipkg.cpp +++ b/noncore/settings/packagemanager/oipkg.cpp @@ -15,93 +15,97 @@ _;:, .> :=|. This program is free software; you can .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "oipkg.h" #include <qdir.h> #include <qfile.h> #include <qtextstream.h> #include <stdlib.h> +#include <unistd.h> const QString IPKG_CONF = "/etc/ipkg.conf"; // Fully-qualified name of Ipkg primary configuration file const QString IPKG_CONF_DIR = "/etc/ipkg"; // Directory of secondary Ipkg configuration files const QString IPKG_PKG_PATH = "/usr/lib/ipkg/lists"; // Directory containing server package lists const QString IPKG_STATUS_PATH = "usr/lib/ipkg/status"; // Destination status file location +const QString IPKG_INFO_PATH = "usr/lib/ipkg/info"; // Package file lists location OIpkg *oipkg; // Ipkg callback functions int fsignalIpkgMessage( ipkg_conf_t *conf, message_level_t level, char *msg ) { + // Display message only if it is below the message level threshold if ( conf && ( conf->verbosity < level ) ) return 0; else oipkg->ipkgMessage( msg ); return 0; } char *fIpkgResponse( char */*question*/ ) { - return 0x0; + return 0l; } int fIpkgStatus( char */*name*/, int /*status*/, char *desc, void */*userdata*/ ) { oipkg->ipkgStatus( desc ); return 0; } int fIpkgFiles( char */*name*/, char *desc, char */*version*/, pkg_state_status_t /*status*/, void */*userdata*/ ) { oipkg->ipkgList( desc ); return 0; } OIpkg::OIpkg( Config *config, QObject *parent, const char *name ) : QObject( parent, name ) , m_config( config ) , m_confInfo( NULL ) , m_ipkgExecOptions( 0 ) , m_ipkgExecVerbosity( 1 ) { + // Keep pointer to self for the Ipkg callback functions oipkg = this; // Initialize libipkg ipkg_init( &fsignalIpkgMessage, &fIpkgResponse, &m_ipkgArgs ); // Default ipkg run-time arguments m_ipkgArgs.noaction = false; m_ipkgArgs.force_defaults = true; } OIpkg::~OIpkg() { // Upon destruction, ensure that items in config list are deleted with list if ( m_confInfo ) m_confInfo->setAutoDelete( true ); // Free up libipkg resources ipkg_deinit( &m_ipkgArgs ); } OConfItemList *OIpkg::configItems() { // Retrieve all configuration items return filterConfItems(); @@ -341,128 +345,161 @@ OPackageList *OIpkg::installedPackages( const QString &destName, const QString & name = value; else if ( key == "Version" ) version = value; else if ( key == "Status" ) status = value; else if ( key.isEmpty() && value.isEmpty() ) newPackage = true; // Skip past all description lines if ( key == "Description" ) { line = t.readLine(); while ( !line.isEmpty() && line.find( ':', 0 ) == -1 && !t.eof() ) line = t.readLine(); } else line = t.readLine(); } f.close(); return pl; } +OConfItem *OIpkg::findConfItem( OConfItem::Type type, const QString &name ) +{ + // Find configuration item in list + OConfItemListIterator configIt( *m_confInfo ); + OConfItem *config = 0l; + for ( ; configIt.current(); ++configIt ) + { + config = configIt.current(); + if ( config->type() == type && config->name() == name ) + break; + } + + if ( config && config->type() == type && config->name() == name ) + return config; + + return 0l; +} + bool OIpkg::executeCommand( OPackage::Command command, const QStringList ¶meters, const QString &destination, const QObject *receiver, const char *slotOutput, bool rawOutput ) { if ( command == OPackage::NotDefined ) return false; // Set ipkg run-time options/arguments m_ipkgArgs.force_depends = ( m_ipkgExecOptions & FORCE_DEPENDS ); m_ipkgArgs.force_reinstall = ( m_ipkgExecOptions & FORCE_REINSTALL ); // TODO m_ipkgArgs.force_remove = ( m_ipkgExecOptions & FORCE_REMOVE ); m_ipkgArgs.force_overwrite = ( m_ipkgExecOptions & FORCE_OVERWRITE ); m_ipkgArgs.verbosity = m_ipkgExecVerbosity; if ( m_ipkgArgs.dest ) free( m_ipkgArgs.dest ); if ( !destination.isNull() ) { int len = destination.length() + 1; m_ipkgArgs.dest = (char *)malloc( len ); strncpy( m_ipkgArgs.dest, destination, destination.length() ); m_ipkgArgs.dest[ len - 1 ] = '\0'; } else - m_ipkgArgs.dest = 0x0; + m_ipkgArgs.dest = 0l; // Connect output signal to widget - if ( rawOutput ) - { -// if ( slotOutput ) -// connect( this, SIGNAL(signalIpkgMessage(char*)), receiver, slotOutput ); - } - else + if ( !rawOutput ) { // TODO - connect to local slot and parse output before emitting signalIpkgMessage } switch( command ) { case OPackage::Update : { - connect( this, SIGNAL(signalIpkgMessage(char*)), receiver, slotOutput ); + connect( this, SIGNAL(signalIpkgMessage(const QString &)), receiver, slotOutput ); ipkg_lists_update( &m_ipkgArgs ); }; break; case OPackage::Upgrade : { - connect( this, SIGNAL(signalIpkgMessage(char*)), receiver, slotOutput ); + connect( this, SIGNAL(signalIpkgMessage(const QString &)), receiver, slotOutput ); ipkg_packages_upgrade( &m_ipkgArgs ); + + // Re-link non-root destinations to make sure everything is in sync + OConfItemList *destList = destinations(); + OConfItemListIterator it( *destList ); + for ( ; it.current(); ++it ) + { + OConfItem *dest = it.current(); + if ( dest->name() != "root" ) + linkPackageDir( dest->name() ); + } + delete destList; }; break; case OPackage::Install : { - connect( this, SIGNAL(signalIpkgMessage(char*)), receiver, slotOutput ); + connect( this, SIGNAL(signalIpkgMessage(const QString &)), receiver, slotOutput ); for ( QStringList::ConstIterator it = parameters.begin(); it != parameters.end(); ++it ) { ipkg_packages_install( &m_ipkgArgs, (*it) ); } + if ( destination != "root" ) + linkPackageDir( destination ); }; break; case OPackage::Remove : { - connect( this, SIGNAL(signalIpkgMessage(char*)), receiver, slotOutput ); + connect( this, SIGNAL(signalIpkgMessage(const QString &)), receiver, slotOutput ); + + // Get list of destinations for unlinking of packages not installed to root + OConfItemList *destList = destinations(); + for ( QStringList::ConstIterator it = parameters.begin(); it != parameters.end(); ++it ) { + unlinkPackage( (*it), destList ); ipkg_packages_remove( &m_ipkgArgs, (*it), true ); } + + delete destList; }; break; case OPackage::Download : { - connect( this, SIGNAL(signalIpkgMessage(char*)), receiver, slotOutput ); + connect( this, SIGNAL(signalIpkgMessage(const QString &)), receiver, slotOutput ); for ( QStringList::ConstIterator it = parameters.begin(); it != parameters.end(); ++it ) { ipkg_packages_download( &m_ipkgArgs, (*it) ); } }; break; case OPackage::Info : { - connect( this, SIGNAL(signalIpkgStatus(char*)), receiver, slotOutput ); - ipkg_packages_info( &m_ipkgArgs, (*parameters.begin()), &fIpkgStatus, 0x0 ); + connect( this, SIGNAL(signalIpkgStatus(const QString &)), receiver, slotOutput ); + ipkg_packages_info( &m_ipkgArgs, (*parameters.begin()), &fIpkgStatus, 0l ); }; break; case OPackage::Files : { - connect( this, SIGNAL(signalIpkgList(char*)), receiver, slotOutput ); - ipkg_package_files( &m_ipkgArgs, (*parameters.begin()), &fIpkgFiles, 0x0 ); + connect( this, SIGNAL(signalIpkgList(const QString &)), receiver, slotOutput ); + ipkg_package_files( &m_ipkgArgs, (*parameters.begin()), &fIpkgFiles, 0l ); }; break; default : break; }; return true; } void OIpkg::ipkgMessage( char *msg ) { emit signalIpkgMessage( msg ); } void OIpkg::ipkgStatus( char *status ) { emit signalIpkgStatus( status ); } void OIpkg::ipkgList( char *filelist ) { emit signalIpkgList( filelist ); } void OIpkg::loadConfiguration() @@ -568,24 +605,161 @@ OConfItemList *OIpkg::filterConfItems( OConfItem::Type typefilter ) { // Load Ipkg configuration info if not already cached if ( !m_confInfo ) loadConfiguration(); // Build new server list (caller is responsible for deleting) OConfItemList *sl = new OConfItemList; // If typefilter is empty, retrieve all items bool retrieveAll = ( typefilter == OConfItem::NotDefined ); // Parse configuration info for servers OConfItemListIterator it( *m_confInfo ); for ( ; it.current(); ++it ) { OConfItem *item = it.current(); if ( retrieveAll || item->type() == typefilter ) { sl->append( item ); } } return sl; } + +const QString &OIpkg::rootPath() +{ + if ( m_rootPath.isEmpty() ) + { + OConfItem *rootDest = findConfItem( OConfItem::Destination, "root" ); + rootDest ? m_rootPath = rootDest->value() + : m_rootPath = '/'; + if ( m_rootPath.right( 1 ) == '/' ) + m_rootPath.truncate( m_rootPath.length() - 1 ); + } + return m_rootPath; +} + +void OIpkg::linkPackageDir( const QString &dest ) +{ + if ( !dest.isNull() ) + { + OConfItem *destConfItem = findConfItem( OConfItem::Destination, dest ); + + emit signalIpkgMessage( tr( "Linking packages installed in: %1" ).arg( dest ) ); + + // Set package destination directory + QString destDir = destConfItem->value(); + QString destInfoDir = destDir; + if ( destInfoDir.right( 1 ) != '/' ) + destInfoDir.append( '/' ); + destInfoDir.append( IPKG_INFO_PATH ); + + // Get list of installed packages in destination + QDir packageDir( destInfoDir ); + QStringList packageFiles; + if ( packageDir.exists() ) + { + packageDir.setNameFilter( "*.list" ); + packageDir.setFilter( QDir::Files ); + packageFiles = packageDir.entryList( "*.list", QDir::Files ); + } + + // Link all files for every package installed in desination + QStringList::Iterator lastFile = packageFiles.end(); + for ( QStringList::Iterator it = packageFiles.begin(); it != lastFile; ++it ) + { + //emit signalIpkgMessage( QString( "Processing: %1/%2" ).arg( destInfoDir ).arg (*it) ); + QString packageFileName = destInfoDir; + packageFileName.append( '/' ); + packageFileName.append( (*it) ); + QFile packageFile( packageFileName ); + if ( packageFile.open( IO_ReadOnly ) ) + { + QTextStream t( &packageFile ); + QString linkFile; + while ( !t.eof() ) + { + // Get the name of the file to link and build the sym link filename + linkFile = t.readLine(); + QString linkDest( linkFile.right( linkFile.length() - destDir.length() ) ); + linkDest.prepend( rootPath() ); + + // If file installed file is actually symbolic link, use actual file for linking + QFileInfo fileInfo( linkFile ); + if ( fileInfo.isSymLink() && !fileInfo.readLink().isEmpty() ) + linkFile = fileInfo.readLink(); + + // See if directory exists in 'root', if not, create + fileInfo.setFile( linkDest ); + QString linkDestDirName = fileInfo.dirPath( true ); + QDir linkDestDir( linkDestDirName ); + if ( !linkDestDir.exists() ) + { + linkDestDir.mkdir( linkDestDirName ); + } + else + { + // Remove any previous link to make sure we will be pointing to the current version + if ( QFile::exists( linkDest ) ) + QFile::remove( linkDest ); + } + + // Link the file + //emit signalIpkgMessage( QString( "Linking '%1' to '%2'" ).arg( linkFile ).arg( linkDest ) ); + if ( symlink( linkFile, linkDest ) == -1 ) + emit signalIpkgMessage( tr( "Error linkling '%1' to '%2'" ) + .arg( linkFile ) + .arg( linkDest ) ); + } + packageFile.close(); + } + } + } +} + +void OIpkg::unlinkPackage( const QString &package, OConfItemList *destList ) +{ + if ( !package.isNull() ) + { + // Find destination package is installed in + if ( destList ) + { + OConfItemListIterator it( *destList ); + for ( ; it.current(); ++it ) + { + OConfItem *dest = it.current(); + QString destInfoFileName = QString( "%1/%2/%3.list" ).arg( dest->value() ) + .arg( IPKG_INFO_PATH ) + .arg( package ); + //emit signalIpkgMessage( QString( "Looking for '%1'" ).arg ( destInfoFileName ) ); + + // If found and destination is not 'root', remove symbolic links + if ( QFile::exists( destInfoFileName ) && dest->name() != "root" ) + { + QFile destInfoFile( destInfoFileName ); + if ( destInfoFile.open( IO_ReadOnly ) ) + { + QTextStream t( &destInfoFile ); + QString linkFile; + while ( !t.eof() ) + { + // Get the name of the file to link and build the sym link filename + linkFile = t.readLine(); + QString linkDest( linkFile.right( linkFile.length() - + dest->value().length() ) ); + linkDest.prepend( rootPath() ); + + //emit signalIpkgMessage( QString( "Deleting: '%1'" ).arg( linkDest ) ); + QFile::remove( linkDest ); + } + destInfoFile.close(); + } + + emit signalIpkgMessage( tr( "Links removed for: %1" ).arg( package ) ); + return; + } + } + } + } +} diff --git a/noncore/settings/packagemanager/oipkg.h b/noncore/settings/packagemanager/oipkg.h index 3c96200..0263f50 100644 --- a/noncore/settings/packagemanager/oipkg.h +++ b/noncore/settings/packagemanager/oipkg.h @@ -35,74 +35,82 @@ _;:, .> :=|. This program is free software; you can #include "oconfitem.h" #include "opackage.h" #include <qpe/config.h> #include <qobject.h> extern "C" { #include <libipkg.h> }; // Ipkg execution options (m_ipkgExecOptions) #define FORCE_DEPENDS 0x0001 #define FORCE_REMOVE 0x0002 #define FORCE_REINSTALL 0x0004 #define FORCE_OVERWRITE 0x0008 class OConfItemList; class OIpkg : public QObject { Q_OBJECT public: - OIpkg( Config *config = 0x0, QObject *parent = 0x0, const char *name = 0x0 ); + OIpkg( Config *config = 0l, QObject *parent = 0l, const char *name = 0l ); ~OIpkg(); OConfItemList *configItems(); OConfItemList *servers(); OConfItemList *destinations(); OConfItemList *options(); int ipkgExecOptions() { return m_ipkgExecOptions; } int ipkgExecVerbosity() { return m_ipkgExecVerbosity; } void setConfigItems( OConfItemList *configList ); void setIpkgExecOptions( int options ) { m_ipkgExecOptions = options; } void setIpkgExecVerbosity( int verbosity ) { m_ipkgExecVerbosity = verbosity; } void saveSettings(); OPackageList *availablePackages( const QString &server = QString::null ); OPackageList *installedPackages( const QString &destName = QString::null, const QString &destPath = QString::null ); + OConfItem *findConfItem( OConfItem::Type type = OConfItem::NotDefined, + const QString &name = QString::null ); + bool executeCommand( OPackage::Command command = OPackage::NotDefined, const QStringList ¶meters = QStringList(), const QString &destination = QString::null, - const QObject *receiver = 0x0, - const char *slotOutput = 0x0, + const QObject *receiver = 0l, + const char *slotOutput = 0l, bool rawOutput = true ); void abortCommand(); void ipkgMessage( char *msg ); void ipkgStatus( char *status ); void ipkgList( char *filelist ); private: Config *m_config; // Pointer to application configuration file args_t m_ipkgArgs; // libipkg configuration arguments OConfItemList *m_confInfo; // Contains info from all Ipkg configuration files int m_ipkgExecOptions; // Bit-mapped flags for Ipkg execution options int m_ipkgExecVerbosity; // Ipkg execution verbosity level + QString m_rootPath; // Directory path where the 'root' destination is located void loadConfiguration(); OConfItemList *filterConfItems( OConfItem::Type typefilter = OConfItem::NotDefined ); + const QString &rootPath(); + void linkPackageDir( const QString &dest = QString::null ); + void unlinkPackage( const QString &package = QString::null, + OConfItemList *destList = 0l ); signals: - void signalIpkgMessage( char *msg ); - void signalIpkgStatus( char *status ); - void signalIpkgList( char *filelist ); + void signalIpkgMessage( const QString &msg ); + void signalIpkgStatus( const QString &status ); + void signalIpkgList( const QString &filelist ); }; #endif diff --git a/noncore/settings/packagemanager/oipkgconfigdlg.cpp b/noncore/settings/packagemanager/oipkgconfigdlg.cpp index 77ad220..e6d6a81 100644 --- a/noncore/settings/packagemanager/oipkgconfigdlg.cpp +++ b/noncore/settings/packagemanager/oipkgconfigdlg.cpp @@ -71,78 +71,78 @@ OIpkgConfigDlg::OIpkgConfigDlg( OIpkg *ipkg, bool installOptions, QWidget *paren initData(); // Setup tabs for all info m_layout.addWidget( &m_tabWidget ); if ( !m_installOptions ) { m_tabWidget.addTab( m_serverWidget, "packagemanager/servertab", tr( "Servers" ) ); m_tabWidget.addTab( m_destWidget, "packagemanager/desttab", tr( "Destinations" ) ); m_tabWidget.addTab( m_proxyWidget, "packagemanager/proxytab", tr( "Proxies" ) ); m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); m_tabWidget.setCurrentTab( tr( "Servers" ) ); } else { m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); } } void OIpkgConfigDlg::accept() { // Save server, destination and proxy configuration if ( !m_installOptions ) { // Update proxy information before saving settings - OConfItem *confItem = findConfItem( OConfItem::Option, "http_proxy" ); + OConfItem *confItem = m_ipkg->findConfItem( OConfItem::Option, "http_proxy" ); if ( confItem ) { confItem->setValue( m_proxyHttpServer->text() ); confItem->setActive( m_proxyHttpActive->isChecked() ); } else m_configs->append( new OConfItem( OConfItem::Option, "http_proxy", m_proxyHttpServer->text(), QString::null, m_proxyHttpActive->isChecked() ) ); - confItem = findConfItem( OConfItem::Option, "ftp_proxy" ); + confItem = m_ipkg->findConfItem( OConfItem::Option, "ftp_proxy" ); if ( confItem ) { confItem->setValue( m_proxyFtpServer->text() ); confItem->setActive( m_proxyFtpActive->isChecked() ); } else m_configs->append( new OConfItem( OConfItem::Option, "ftp_proxy", m_proxyFtpServer->text(), QString::null, m_proxyFtpActive->isChecked() ) ); - confItem = findConfItem( OConfItem::Option, "proxy_username" ); + confItem = m_ipkg->findConfItem( OConfItem::Option, "proxy_username" ); if ( confItem ) confItem->setValue( m_proxyUsername->text() ); else m_configs->append( new OConfItem( OConfItem::Option, "proxy_username", m_proxyUsername->text() ) ); - confItem = findConfItem( OConfItem::Option, "proxy_password" ); + confItem = m_ipkg->findConfItem( OConfItem::Option, "proxy_password" ); if ( confItem ) confItem->setValue( m_proxyPassword->text() ); else m_configs->append( new OConfItem( OConfItem::Option, "proxy_password", m_proxyPassword->text() ) ); m_ipkg->setConfigItems( m_configs ); } // Save options configuration int options = 0; if ( m_optForceDepends->isChecked() ) options |= FORCE_DEPENDS; if ( m_optForceReinstall->isChecked() ) options |= FORCE_REINSTALL; if ( m_optForceRemove->isChecked() ) options |= FORCE_REMOVE; if ( m_optForceOverwrite->isChecked() ) options |= FORCE_OVERWRITE; m_ipkg->setIpkgExecOptions( options ); m_ipkg->setIpkgExecVerbosity( m_optVerboseIpkg->currentItem() ); QDialog::accept(); } @@ -372,177 +372,159 @@ void OIpkgConfigDlg::initData() else if ( config->name() == "proxy_password" ) { m_proxyPassword->setText( config->value() ); } } } } } } // Get Ipkg execution options int options = m_ipkg->ipkgExecOptions(); if ( options & FORCE_DEPENDS ) m_optForceDepends->setChecked( true ); if ( options & FORCE_REINSTALL ) m_optForceReinstall->setChecked( true ); if ( options & FORCE_REMOVE ) m_optForceRemove->setChecked( true ); if ( options & FORCE_OVERWRITE ) m_optForceOverwrite->setChecked( true ); m_optVerboseIpkg->setCurrentItem( m_ipkg->ipkgExecVerbosity() ); } -OConfItem *OIpkgConfigDlg::findConfItem( OConfItem::Type type, const QString &name ) -{ - // Find selected server in list - OConfItemListIterator configIt( *m_configs ); - OConfItem *config = 0l; - for ( ; configIt.current(); ++configIt ) - { - config = configIt.current(); - if ( config->type() == type && config->name() == name ) - break; - } - - if ( config && config->type() == type && config->name() == name ) - return config; - - return 0l; -} - void OIpkgConfigDlg::slotServerSelected( int index ) { m_serverCurrent = index; // Enable Edit and Delete buttons m_serverEditBtn->setEnabled( true ); m_serverDeleteBtn->setEnabled( true ); } void OIpkgConfigDlg::slotServerNew() { OConfItem *server = new OConfItem( OConfItem::Source ); OIpkgServerDlg dlg( server, this ); if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) { // Add to configuration option list m_configs->append( server ); m_configs->sort(); // Add to server list m_serverList->insertItem( server->name() ); m_serverList->setCurrentItem( m_serverList->count() ); } else delete server; } void OIpkgConfigDlg::slotServerEdit() { // Find selected server in list - OConfItem *server = findConfItem( OConfItem::Source, m_serverList->currentText() ); + OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() ); // Edit server if ( server ) { QString origName = server->name(); OIpkgServerDlg dlg( server, this ); if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) { // Check to see if name has changed, if so update the server list if ( server->name() != origName ) m_serverList->changeItem( server->name(), m_serverCurrent ); } } } void OIpkgConfigDlg::slotServerDelete() { // Find selected server in list - OConfItem *server = findConfItem( OConfItem::Source, m_serverList->currentText() ); + OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() ); // Delete server if ( server ) { m_configs->removeRef( server ); m_serverList->removeItem( m_serverCurrent ); } } void OIpkgConfigDlg::slotDestSelected( int index ) { m_destCurrent = index; // Enable Edit and Delete buttons m_destEditBtn->setEnabled( true ); m_destDeleteBtn->setEnabled( true ); } void OIpkgConfigDlg::slotDestNew() { OConfItem *dest = new OConfItem( OConfItem::Destination ); OIpkgDestDlg dlg( dest, this ); if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) { // Add to configuration option list m_configs->append( dest ); m_configs->sort(); // Add to destination list m_destList->insertItem( dest->name() ); m_destList->setCurrentItem( m_destList->count() ); } else delete dest; } void OIpkgConfigDlg::slotDestEdit() { // Find selected destination in list - OConfItem *dest = findConfItem( OConfItem::Destination, m_destList->currentText() ); + OConfItem *dest = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() ); // Edit destination if ( dest ) { QString origName = dest->name(); OIpkgDestDlg dlg( dest, this ); if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) { // Check to see if name has changed, if so update the dest list if ( dest->name() != origName ) m_destList->changeItem( dest->name(), m_destCurrent ); } } } void OIpkgConfigDlg::slotDestDelete() { // Find selected destination in list - OConfItem *destination = findConfItem( OConfItem::Destination, m_destList->currentText() ); + OConfItem *destination = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() ); // Delete destination if ( destination ) { m_configs->removeRef( destination ); m_destList->removeItem( m_destCurrent ); } } OIpkgServerDlg::OIpkgServerDlg( OConfItem *server, QWidget *parent ) : QDialog( parent, QString::null, true, WStyle_ContextHelp ) , m_server( server ) { setCaption( tr( "Edit Server" ) ); // Initialize UI QVBoxLayout *layout = new QVBoxLayout( this, 2, 4 ); m_active = new QCheckBox( tr( "Active" ), this ); QWhatsThis::add( m_active, tr( "Tap here to indicate whether this entry is active or not." ) ); layout->addWidget( m_active ); layout->addStretch(); diff --git a/noncore/settings/packagemanager/oipkgconfigdlg.h b/noncore/settings/packagemanager/oipkgconfigdlg.h index 5b7e91d..0fb2e16 100644 --- a/noncore/settings/packagemanager/oipkgconfigdlg.h +++ b/noncore/settings/packagemanager/oipkgconfigdlg.h @@ -86,51 +86,48 @@ private: QPushButton *m_destDeleteBtn; // Destination edit button // Proxy server configuration UI controls QLineEdit *m_proxyHttpServer; // HTTP proxy server URL edit box QCheckBox *m_proxyHttpActive; // Activate HTTP proxy check box QLineEdit *m_proxyFtpServer; // FTP proxy server edit box QCheckBox *m_proxyFtpActive; // Activate FTP proxy check box QLineEdit *m_proxyUsername; // Proxy server username edit box QLineEdit *m_proxyPassword; // Proxy server password edit box // Options configuration UI controls QCheckBox *m_optForceDepends; // Force depends ipkg option checkbox QCheckBox *m_optForceReinstall; // Force reinstall ipkg option checkbox QCheckBox *m_optForceRemove; // Force remove ipkg option checkbox QCheckBox *m_optForceOverwrite; // Force overwrite ipkg option checkbox QComboBox *m_optVerboseIpkg; // Ipkg verbosity option selection void initServerWidget(); void initDestinationWidget(); void initProxyWidget(); void initOptionsWidget(); void initData(); - OConfItem *findConfItem( OConfItem::Type type = OConfItem::NotDefined, - const QString &name = QString::null ); - private slots: void slotServerSelected( int index ); void slotServerNew(); void slotServerEdit(); void slotServerDelete(); void slotDestSelected( int index ); void slotDestNew(); void slotDestEdit(); void slotDestDelete(); }; class OIpkgServerDlg : public QDialog { Q_OBJECT public: OIpkgServerDlg( OConfItem *server = 0l, QWidget *parent = 0l ); protected slots: void accept(); private: OConfItem *m_server; diff --git a/noncore/settings/packagemanager/opackagemanager.cpp b/noncore/settings/packagemanager/opackagemanager.cpp index cbddfe7..c9fdec1 100644 --- a/noncore/settings/packagemanager/opackagemanager.cpp +++ b/noncore/settings/packagemanager/opackagemanager.cpp @@ -248,67 +248,49 @@ QStringList OPackageManager::servers() } QStringList OPackageManager::destinations() { QStringList dl; OConfItemList *destList = m_ipkg.destinations(); if ( destList ) { for ( OConfItemListIterator destIt( *destList ); destIt.current(); ++destIt ) { OConfItem *destination = destIt.current(); // Add only active destinations if ( destination->active() ) dl << destination->name(); } } return dl; } OConfItem *OPackageManager::findConfItem( OConfItem::Type type, const QString &name ) { - OConfItem *confItem = 0x0; - OConfItemList *confList = m_ipkg.configItems(); - if ( confList ) - { - for ( OConfItemListIterator confIt( *confList ); confIt.current(); ++confIt ) - { - OConfItem *conf = confIt.current(); - - // Add only active confinations - if ( conf->type() == type && conf->name() == name ) - { - confItem = conf; - break; - } - } - } - - return confItem; - + return m_ipkg.findConfItem( type, name ); } OPackage *OPackageManager::findPackage( const QString &name ) { return m_packages[ name ]; } int OPackageManager::compareVersions( const QString &ver1, const QString &ver2 ) { // TODO - should this be in OIpkg??? int epoch1, epoch2; QString version1, revision1; QString version2, revision2; parseVersion( ver1, &epoch1, &version1, &revision1 ); parseVersion( ver2, &epoch2, &version2, &revision2 ); if ( epoch1 > epoch2 ) return 1; else if ( epoch1 < epoch2 ) return -1; int r = verrevcmp( version1.latin1(), version2.latin1() ); diff --git a/noncore/settings/packagemanager/opie-packagemanager.control b/noncore/settings/packagemanager/opie-packagemanager.control index cdf419c..da3ddfe 100644 --- a/noncore/settings/packagemanager/opie-packagemanager.control +++ b/noncore/settings/packagemanager/opie-packagemanager.control @@ -1,10 +1,10 @@ Package: opie-packagemanager Files: plugins/application/libpackagemanager.so* bin/packagemanager pics/packagemanager apps/Settings/packagemanager.desktop Priority: optional Section: opie/settings -Depends: task-opie-minimal, libopiecore2, libopieui2, libipkg (>=0.99.120), ipkg-link +Depends: task-opie-minimal, libopiecore2, libopieui2, libipkg (>=0.99.120) Replaces: packagemanager Architecture: arm Maintainer: Dan Williams (drw@handhelds.org) Description: Opie package management client -Version: 0.6.0$EXTRAVERSION +Version: 0.6.1$EXTRAVERSION diff --git a/noncore/settings/packagemanager/packageinfodlg.cpp b/noncore/settings/packagemanager/packageinfodlg.cpp index 5f72a67..3eef939 100644 --- a/noncore/settings/packagemanager/packageinfodlg.cpp +++ b/noncore/settings/packagemanager/packageinfodlg.cpp @@ -55,49 +55,50 @@ PackageInfoDlg::PackageInfoDlg( QWidget *parent, OPackageManager *pm, const QStr Opie::Ui::OTabWidget *tabWidget = new Opie::Ui::OTabWidget( this ); layout->addWidget( tabWidget ); // Information tab QWhatsThis::add( &m_information, tr( "This area contains information about the package." ) ); m_information.reparent( tabWidget, QPoint( 0, 0 ) ); m_information.setReadOnly( true ); tabWidget->addTab( &m_information, "UtilsIcon", tr( "Information" ) ); // Retrive package information m_package = m_packman->findPackage( package ); if ( !m_package ) { m_information.setText( tr( "Unable to retrieve package information." ) ); return; } // Display package information if ( !m_package->information().isNull() ) m_information.setText( m_package->information() ); else { // Package information is not cached, retrieve it QStringList list( package ); - m_packman->executeCommand( OPackage::Info, list, QString::null, this, SLOT(slotInfo(char*)), true ); + m_packman->executeCommand( OPackage::Info, list, QString::null, + this, SLOT(slotInfo(const QString &)), true ); } // Files tab (display only if package is installed) if ( !m_package->versionInstalled().isNull() ) { QWidget *filesWidget = new QWidget( tabWidget ); QVBoxLayout *filesLayout = new QVBoxLayout( filesWidget, 2, 2 ); QWhatsThis::add( &m_files, tr( "This area contains a list of files contained in this package." ) ); m_files.reparent( filesWidget, QPoint( 0, 0 ) ); m_files.setReadOnly( true ); filesLayout->addWidget( &m_files ); // If file list is already cached, display if ( !m_package->files().isNull() ) m_files.setText( m_package->files() ); else { m_retrieveFiles = new QPushButton( Resource::loadPixmap( "packagemanager/apply" ), tr( "Retrieve file list" ), filesWidget ); QWhatsThis::add( m_retrieveFiles, tr( "Tap here to retrieve list of files contained in this package." ) ); filesLayout->addWidget( m_retrieveFiles ); connect( m_retrieveFiles, SIGNAL(clicked()), this, SLOT(slotBtnFileScan()) ); } @@ -107,45 +108,46 @@ PackageInfoDlg::PackageInfoDlg( QWidget *parent, OPackageManager *pm, const QStr } else m_files.hide(); } PackageInfoDlg::~PackageInfoDlg() { if ( !m_package ) return; // Cache package information if ( !m_information.text().isNull() ) m_package->setInformation( m_information.text() ); // Cache package file list if ( !m_files.text().isEmpty() ) m_package->setFiles( m_files.text() ); } void PackageInfoDlg::slotBtnFileScan() { m_files.clear(); QStringList list( m_package->name() ); - m_packman->executeCommand( OPackage::Files, list, QString::null, this, SLOT(slotFiles(char*)), true ); + m_packman->executeCommand( OPackage::Files, list, QString::null, + this, SLOT(slotFiles(const QString &)), true ); if ( m_retrieveFiles ) m_retrieveFiles->hide(); } -void PackageInfoDlg::slotInfo( char *info ) +void PackageInfoDlg::slotInfo( const QString &info ) { m_information.append( info ); } -void PackageInfoDlg::slotFiles( char *filelist ) +void PackageInfoDlg::slotFiles( const QString &filelist ) { QString str = filelist; // Skip first line of output ("Package xxx is installed...") if ( str.startsWith( "Package " ) ) str = str.right( str.length() - str.find( '\n' ) - 1 ); m_files.append( str ); } diff --git a/noncore/settings/packagemanager/packageinfodlg.h b/noncore/settings/packagemanager/packageinfodlg.h index d1830de..2962f9a 100644 --- a/noncore/settings/packagemanager/packageinfodlg.h +++ b/noncore/settings/packagemanager/packageinfodlg.h @@ -38,29 +38,29 @@ _;:, .> :=|. This file is free software; you can class QPushButton; class OPackage; class OPackageManager; class PackageInfoDlg : public QWidget { Q_OBJECT public: PackageInfoDlg( QWidget *parent = 0l, OPackageManager *pm = 0l, const QString &package = QString::null ); ~PackageInfoDlg(); private: OPackageManager *m_packman; // Pointer to application instance of package manager OPackage *m_package; // Pointer to package to display information for // UI controls QMultiLineEdit m_information; // Multi-line edit to display package information QMultiLineEdit m_files; // Multi-line edit to display package file list QPushButton *m_retrieveFiles; // Push button to retrieve file list private slots: void slotBtnFileScan(); - void slotInfo( char *info ); - void slotFiles( char *filelist ); + void slotInfo( const QString &info ); + void slotFiles( const QString &filelist ); }; #endif |