+2011-10-07 Keith Marshall <keithmarshall@users.sourceforge.net>
+
+ Add support for non-specific upgrade of all installed packages.
+
+ * src/pkgbase.h (pkgXmlDocument::RescheduleInstalledPackages):
+ New public method; declare it.
+
+ * src/pkgdeps.cpp (pkgXmlDocument::RescheduleInstalledPackages):
+ Implement it.
+
+ * src/climain.cpp (climain) [ACTION_UPGRADE && argc < 2]: Invoke
+ pkgXmlDocument::RescheduleInstalledPackages() to schedule the upgrade
+ request for all packages currently registered as installed.
+
2011-10-06 Keith Marshall <keithmarshall@users.sourceforge.net>
Implement "source" and "licence" operations.
delete pkgProcessedArchives;
break;
+ case ACTION_UPGRADE:
+ if( argc < 2 )
+ /*
+ * This is a special case of the upgrade request, for which
+ * no explicit package names have been specified; in this case
+ * we retrieve the list of all installed packages, scheduling
+ * each of them for upgrade...
+ */
+ dbase.RescheduleInstalledPackages( ACTION_UPGRADE );
+
+ /* ...subsequently falling through to complete the action,
+ * using the default processing mechanism; (note that in this
+ * case no further scheduling will be performed, because there
+ * are no additional package names specified in the argv list).
+ */
default:
/* ...schedule the specified action for each additional command line
* argument, (each of which is assumed to represent a package name)...
*/
while( --argc )
+ /*
+ * (Skipped if argv < 2 on entry).
+ */
dbase.Schedule( (unsigned long)(action), *++argv );
/* ...finally, execute all scheduled actions, and update the
dbase.UpdateSystemMap();
}
}
-
/* If we get this far, then all actions completed successfully;
* we are done.
*/
dmh_notify( DMH_ERROR, pkgMsgUnknownPackage(), name );
}
+void pkgXmlDocument::RescheduleInstalledPackages( unsigned long action )
+{
+ /* Wrapper function to retrieve the list of all installed packages,
+ * passing each entry in turn to the standard task scheduler. We
+ * begin by locating the first sysroot entry in the XML database...
+ */
+ pkgXmlNode *sysroot = GetRoot()->FindFirstAssociate( sysroot_key );
+
+ /* ...then, while we have sysroots to examine...
+ */
+ while( sysroot != NULL )
+ {
+ /* ...we retrieve the first package installation record within
+ * the current sysroot data set.
+ */
+ pkgXmlNode *package = sysroot->FindFirstAssociate( installed_key );
+
+ /* Within each sysroot, until we've retrieved all embedded
+ * installation records...
+ */
+ while( package != NULL )
+ {
+ /* ...we read the canonical tarname for the package,
+ * and when it is appropriately specified...
+ */
+ const char *tarname = package->GetPropVal( tarname_key, NULL );
+ if( tarname != NULL )
+ {
+ /* ...we decode it, to determine the package name,
+ * subsystem name and component class.
+ */
+ pkgSpecs decode( tarname );
+ const char *pkgname = decode.GetPackageName();
+ const char *sysname = decode.GetSubSystemName();
+ const char *cptname = decode.GetComponentClass();
+
+ /* From these three, we need to reconstruct an effective
+ * package name for the scheduler look-up; this reconstruction
+ * is performed using the following formatted buffer.
+ */
+ const char *fmt = "%s-%s";
+ char refname[3 + strlen( sysname ) + strlen( pkgname ) + strlen( cptname )];
+ if( FindPackageByName( pkgname, sysname ) == NULL )
+ {
+ /* The package name alone is insufficient for a successful
+ * look-up; assume that the effective package name has been
+ * defined by prefixing the sysroot name.
+ */
+ sprintf( refname, fmt, sysname, pkgname );
+ pkgname = refname;
+ }
+ if( cptname != NULL )
+ {
+ /* A fully qualified logical package name should include
+ * the component class name, abstracted from the canonical
+ * tarname, and appended to the package name.
+ */
+ sprintf( refname, fmt, pkgname, cptname );
+ pkgname = refname;
+ }
+
+ /* Having constructed the effective logical package name,
+ * we schedule the requested action on the package...
+ */
+ Schedule( action, pkgname );
+ }
+ /* ...then move on to the next installed package, if any,
+ * within the current sysroot data set...
+ */
+ package = package->FindNextAssociate( installed_key );
+ }
+ /* ...and ultimately, to the next sysroot, if any, in the
+ * XML database.
+ */
+ sysroot = sysroot->FindNextAssociate( sysroot_key );
+ }
+}
+
/* $RCSfile$: end of file */