summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog132
-rw-r--r--components/rpmview/nautilus-rpm-view-install.c2
-rw-r--r--components/services/install/command-line/eazel-alt-install-corba.c2
-rw-r--r--components/services/install/idl/trilobite-eazel-install.idl17
-rw-r--r--components/services/install/lib/eazel-install-corba-callback.c19
-rw-r--r--components/services/install/lib/eazel-install-corba-callback.h6
-rw-r--r--components/services/install/lib/eazel-install-corba-types.c24
-rw-r--r--components/services/install/lib/eazel-install-logic.c1606
-rw-r--r--components/services/install/lib/eazel-install-logic.h11
-rw-r--r--components/services/install/lib/eazel-install-logic2.c442
-rw-r--r--components/services/install/lib/eazel-install-object.c226
-rw-r--r--components/services/install/lib/eazel-install-private.h10
-rw-r--r--components/services/install/lib/eazel-install-problem.c80
-rw-r--r--components/services/install/lib/eazel-install-public.h20
-rw-r--r--components/services/install/lib/eazel-package-system-rpm3.c82
-rw-r--r--components/services/install/lib/eazel-package-system-types.c15
-rw-r--r--components/services/install/lib/eazel-package-system-types.h4
-rw-r--r--components/services/install/lib/eazel-package-system.c10
18 files changed, 1037 insertions, 1671 deletions
diff --git a/ChangeLog b/ChangeLog
index 4d7328f39..3340555ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,135 @@
+2001-02-08 Eskil Heyn Olsen <eskil@eazel.com>
+
+ reviewed by: Robey Pointer <robey@eazel.com>
+
+ This commit fixed bugs:
+ 5723 ei2: check that install_failed_signal was not called
+ 5752 ei2: port the uninstall stuff to the new ei2
+ 5753 ei2: port the revert stuff to ei2
+ 5757 fix leaks in EazelProblemHander
+ 5957 eazel-install cli tool no longer uninstalls nicely
+ 6100 RPM4: don't handle dependencies called "rpmlib(.*)"
+ 6173 ei2: finish conflict and feature breakage
+ 6191 make revert work (ei2: resurrect transaction stuff)
+
+ * components/rpmview/nautilus-rpm-view-install.c:
+ (get_detailed_errors_foreach):
+ Updated for the CANCELLED status.
+ * components/services/install/command-line/eazel-alt-install-corba.
+ c: (eazel_preflight_check_signal):
+ Fixed an output string.
+
+ * components/services/install/idl/trilobite-eazel-install.idl:
+ Added the CANCELLED status.
+ uninstall_progress now has same signature as install_progress.
+
+ * components/services/install/lib/eazel-install-corba-callback.h:
+ * components/services/install/lib/eazel-install-corba-callback.c:
+ (impl_uninstall_progress),
+ (eazel_install_callback_class_initialize):
+ uninstall_progress now has same signature as install_progress.
+
+ * components/services/install/lib/eazel-install-corba-types.c:
+ (corba_packagedatastruct_fill_from_packagedata),
+ (traverse_packagetree_md5), (corba_packagedatastruct_fill_deps),
+ (packagedata_from_corba_packagedatastruct),
+ (packagedata_tree_from_corba_packagedatastructlist),
+ (categorydata_list_from_corba_categorystructlist):
+ Added the CANCELLED status.
+ Commented out sending ->provides in signals.
+ Added some g_asserts to find a bug.
+ categorydata_list_from_corba_categorystructlist uses
+ packagedata_list_from_corba_packagedatastructlist.
+
+ * components/services/install/lib/eazel-install-logic.h:
+ * components/services/install/lib/eazel-install-logic.c:
+ (eazel_install_start_transaction), (dump_one_package),
+ (compare_break_to_package_by_name),
+ (eazel_uninstall_upward_traverse),
+ (eazel_uninstall_downward_traverse):
+ Threw out most of the old code. Keeping logic.c untill 6190 is
+ closed.
+
+ * components/services/install/lib/eazel-install-logic2.c:
+ (dump_tree_helper), (check_md5_on_files), (is_satisfied),
+ (check_tree_helper), (execute), (set_toplevel),
+ (get_packages_with_mod_flag), (check_uninst_vs_downgrade),
+ (debug_revert), (compare_break_to_package_by_name),
+ (eazel_uninstall_upward_traverse),
+ (eazel_uninstall_check_for_install), (eazel_uninstall_globber),
+ (install_packages), (uninstall_packages), (revert_transaction):
+ Moved revert and uninstall into logic2.c and updated them
+ appropriately.
+ Added paranoia check in case bad xml dependency has a version but
+ an senseless sense.
+ When reviving, set parent->topleve to TRUE, not revived package.
+ Revived the transaction stuff (for revert).
+ Don't allow a package to depend on a package of the same name,
+ this is often a problem during softcat updates.
+
+ * components/services/install/lib/eazel-install-public.h:
+ * components/services/install/lib/eazel-install-private.h:
+ * components/services/install/lib/eazel-install-object.c:
+ (eazel_install_finalize), (eazel_install_start_signal),
+ (eazel_install_end_signal), (eazel_install_progress_signal),
+ (eazel_install_failed_signal), (eazel_install_class_initialize),
+ (eazel_install_initialize), (eazel_install_install_packages),
+ (eazel_install_uninstall_packages),
+ (eazel_install_revert_transaction_from_xmlstring),
+ (eazel_install_do_transaction_save_report_helper),
+ (eazel_install_save_transaction_report),
+ (eazel_install_init_transaction),
+ (eazel_install_emit_uninstall_progress),
+ (eazel_install_emit_uninstall_progress_default),
+ (eazel_install_emit_download_progress):
+ uninstall_progress now has same signature as install_progress.
+ Fixed some dumb bugs in install/uninstall progress emission.
+ Added some lists to check on install status.
+ Moved some of the transaction stuff from logic.c here.
+
+ * components/services/install/lib/eazel-install-problem.c:
+ (get_detailed_messages_foreach),
+ (get_detailed_uninstall_messages_foreach),
+ (get_detailed_cases_foreach),
+ (get_detailed_uninstall_cases_foreach),
+ (eazel_install_problem_tree_to_case),
+ (eazel_install_problem_tree_to_string),
+ (build_categories_from_problem_list):
+ Updated again for the new PackageBreaks objects.
+ Fixed so cli uninstall works nice again.
+ Added the CANCELLED status.
+ The problem handler is deteriorating, either we use it or we scrap
+ it.
+
+ * components/services/install/lib/eazel-package-system-rpm3.c:
+ (rpmmonitorpiggybag_new),
+ (eazel_package_system_rpm3_set_mod_status),
+ (monitor_rpm_process_pipe_percent_output),
+ (eazel_package_system_rpm3_packagedata_fill_from_header),
+ (eazel_package_system_rpm3_set_state),
+ (eazel_package_system_rpm3_execute), (check_if_all_packages_seen),
+ (eazel_package_system_rpm3_install_uninstall):
+ Don't spam about the locales decimal seperator.
+ Set modification status after handling a package, so transaction
+ logs make sense.
+ Don't accept requirements of type "rpmlib(.*".
+ Ability to set all packages to CANCELLED if root helper failed
+ login.
+ If TEST is set, fake success all the time.
+
+ * components/services/install/lib/eazel-package-system-types.h:
+ * components/services/install/lib/eazel-package-system-types.c:
+ (categorydata_new), (categorydata_destroy_foreach),
+ (packagedata_status_enum_to_str),
+ (packagedata_status_str_to_enum):
+ Added the CANCELLED status.
+ Improved the debug strings for alloc/dealloc of category data
+ structures.
+
+ * components/services/install/lib/eazel-package-system.c:
+ (eazel_package_system_install):
+ If TEST, disable FORCE.
+
2001-02-08 John Harper <jsh@eazel.com>
Fixed bug 6044 (Druid should be clearer on what the right
diff --git a/components/rpmview/nautilus-rpm-view-install.c b/components/rpmview/nautilus-rpm-view-install.c
index 69528fad9..18b2e7409 100644
--- a/components/rpmview/nautilus-rpm-view-install.c
+++ b/components/rpmview/nautilus-rpm-view-install.c
@@ -96,7 +96,7 @@ get_detailed_errors_foreach (const PackageData *pack, GString *message)
{
switch (pack->status) {
case PACKAGE_UNKNOWN_STATUS:
- break;
+ case PACKAGE_CANCELLED:
case PACKAGE_SOURCE_NOT_SUPPORTED:
break;
case PACKAGE_FILE_CONFLICT:
diff --git a/components/services/install/command-line/eazel-alt-install-corba.c b/components/services/install/command-line/eazel-alt-install-corba.c
index faff124a0..e2394002d 100644
--- a/components/services/install/command-line/eazel-alt-install-corba.c
+++ b/components/services/install/command-line/eazel-alt-install-corba.c
@@ -556,7 +556,7 @@ eazel_preflight_check_signal (EazelInstallCallback *service,
if (cases) return FALSE;
fprintf (stdout, "About to %s a total of %d packages, %dKb\n",
- arg_erase ? "uninstall" : "install",
+ arg_erase ? "uninstall" : arg_revert ? "revert" : "install",
total_packages, total_bytes/1024);
for (iterator = packages; iterator; iterator = iterator->next) {
PackageData *pack = (PackageData*)iterator->data;
diff --git a/components/services/install/idl/trilobite-eazel-install.idl b/components/services/install/idl/trilobite-eazel-install.idl
index 76c8ee13f..ff10e20b7 100644
--- a/components/services/install/idl/trilobite-eazel-install.idl
+++ b/components/services/install/idl/trilobite-eazel-install.idl
@@ -17,6 +17,7 @@ module Trilobite {
enum PackageStatusEnum {
UNKNOWN_STATUS,
+ CANCELLED, /* medium: Package cancelled, eg wrong password or such */
SOURCE_NOT_SUPPORTED, /* bad: we don't install source packages */
DEPENDENCY_FAIL, /* bad: a dependency failed in next level */
FILE_CONFLICT, /* bad: this file owns a file that the
@@ -181,11 +182,19 @@ module Trilobite {
/* Called during (un)installation of a package */
oneway void install_progress (in PackageDataStruct package,
- in long package_num, in long num_packages,
- in long package_size_completed, in long package_size_total,
- in long total_size_completed, in long total_size);
+ in long package_num,
+ in long num_packages,
+ in long package_size_completed,
+ in long package_size_total,
+ in long total_size_completed,
+ in long total_size);
oneway void uninstall_progress (in PackageDataStruct package,
- in long amount, in long total);
+ in long package_num,
+ in long num_packages,
+ in long package_size_completed,
+ in long package_size_total,
+ in long total_size_completed,
+ in long total_size);
/* Called whenever a package (un)install fails
*/
diff --git a/components/services/install/lib/eazel-install-corba-callback.c b/components/services/install/lib/eazel-install-corba-callback.c
index 5fa53fee8..d0d743504 100644
--- a/components/services/install/lib/eazel-install-corba-callback.c
+++ b/components/services/install/lib/eazel-install-corba-callback.c
@@ -191,13 +191,18 @@ impl_install_progress (impl_POA_GNOME_Trilobite_Eazel_InstallCallback *servant,
static void
impl_uninstall_progress (impl_POA_GNOME_Trilobite_Eazel_InstallCallback *servant,
const GNOME_Trilobite_Eazel_PackageDataStruct *corbapack,
- const CORBA_long amount,
- const CORBA_long total,
- CORBA_Environment * ev)
+ const CORBA_long package_num, const CORBA_long num_packages,
+ const CORBA_long package_size_completed, const CORBA_long package_size_total,
+ const CORBA_long total_size_completed, const CORBA_long total_size,
+ CORBA_Environment * ev)
{
PackageData *pack;
pack = packagedata_from_corba_packagedatastruct (corbapack);
- gtk_signal_emit (GTK_OBJECT (servant->object), signals[UNINSTALL_PROGRESS], pack, amount, total);
+ gtk_signal_emit (GTK_OBJECT (servant->object), signals[UNINSTALL_PROGRESS],
+ pack,
+ package_num, num_packages,
+ package_size_completed, package_size_total,
+ total_size_completed, total_size);
gtk_object_unref (GTK_OBJECT (pack));
}
@@ -429,8 +434,10 @@ eazel_install_callback_class_initialize (EazelInstallCallbackClass *klass)
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (EazelInstallCallbackClass, uninstall_progress),
- gtk_marshal_NONE__POINTER_INT_INT,
- GTK_TYPE_NONE, 3, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_INT);
+ eazel_install_gtk_marshal_NONE__POINTER_INT_INT_INT_INT_INT_INT,
+ GTK_TYPE_NONE, 7,
+ GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_INT,
+ GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT);
signals[DOWNLOAD_FAILED] =
gtk_signal_new ("download_failed",
GTK_RUN_LAST,
diff --git a/components/services/install/lib/eazel-install-corba-callback.h b/components/services/install/lib/eazel-install-corba-callback.h
index 65bec6982..56ed93a36 100644
--- a/components/services/install/lib/eazel-install-corba-callback.h
+++ b/components/services/install/lib/eazel-install-corba-callback.h
@@ -63,7 +63,11 @@ struct _EazelInstallCallbackClass
int package_size_completed, int package_size_total,
int total_size_completed, int total_size);
/* Called during uninstall of a package */
- void (*uninstall_progress) (EazelInstallCallback *service, const PackageData *pack, int amount, int total);
+ void (*uninstall_progress) (EazelInstallCallback *service,
+ const PackageData *pack,
+ int package_num, int num_packages,
+ int package_size_completed, int package_size_total,
+ int total_size_completed, int total_size);
/* Called when a package is undergoing the different checks */
void (*file_conflict_check)(EazelInstallCallback *service, const PackageData *package);
diff --git a/components/services/install/lib/eazel-install-corba-types.c b/components/services/install/lib/eazel-install-corba-types.c
index 1eb0291d4..ad6d4040b 100644
--- a/components/services/install/lib/eazel-install-corba-types.c
+++ b/components/services/install/lib/eazel-install-corba-types.c
@@ -117,17 +117,22 @@ corba_packagedatastruct_fill_from_packagedata (GNOME_Trilobite_Eazel_PackageData
case PACKAGE_ALREADY_INSTALLED:
corbapack->status = GNOME_Trilobite_Eazel_ALREADY_INSTALLED;
break;
+ case PACKAGE_CANCELLED:
+ corbapack->status = GNOME_Trilobite_Eazel_CANCELLED;
+ break;
case PACKAGE_CIRCULAR_DEPENDENCY:
corbapack->status = GNOME_Trilobite_Eazel_CIRCULAR_DEPENDENCY;
break;
}
+/* None of the callback signals wants this....
if (pack->provides) {
g_list_to_corba_string_sequence (&(corbapack->provides), pack->provides);
} else {
corbapack->provides._length = 0;
corbapack->provides._buffer = NULL;
}
+*/
/* depends will be filled in further up, if they're required --
* many times, this function is called to create a single corba package with no other package pointers */
@@ -204,6 +209,7 @@ traverse_packagetree_md5 (const PackageData *pack, GHashTable *md5_table)
g_hash_table_insert (md5_table, pack->md5, (void *)pack);
for (iter = g_list_first (pack->depends); iter != NULL; iter = g_list_next (iter)) {
dep = (PackageDependency *)(iter->data);
+ g_assert (dep);
traverse_packagetree_md5 (dep->package, md5_table);
}
for (iter = g_list_first (pack->breaks); iter != NULL; iter = g_list_next (iter)) {
@@ -244,6 +250,7 @@ corba_packagedatastruct_fill_deps (GNOME_Trilobite_Eazel_PackageDataStruct *corb
dep = (PackageDependency *)(iter->data);
/* set up a PackageDependencyStruct for it */
+ g_assert (dep);
corbadep = &(corbapack->depends._buffer[i]);
sense_str = eazel_softcat_sense_flags_to_string (dep->sense);
corbadep->sense = CORBA_string_dup (sense_str);
@@ -251,6 +258,7 @@ corba_packagedatastruct_fill_deps (GNOME_Trilobite_Eazel_PackageDataStruct *corb
corbadep->package_md5 = CORBA_string_dup (dep->package->md5);
g_free (sense_str);
}
+ g_assert (i!=0);
}
if (pack->breaks != NULL) {
@@ -393,6 +401,9 @@ packagedata_from_corba_packagedatastruct (const GNOME_Trilobite_Eazel_PackageDat
case GNOME_Trilobite_Eazel_ALREADY_INSTALLED:
pack->status = PACKAGE_ALREADY_INSTALLED;
break;
+ case GNOME_Trilobite_Eazel_CANCELLED:
+ pack->status = PACKAGE_CANCELLED;
+ break;
case GNOME_Trilobite_Eazel_CIRCULAR_DEPENDENCY:
pack->status = PACKAGE_CIRCULAR_DEPENDENCY;
break;
@@ -481,6 +492,7 @@ packagedata_tree_from_corba_packagedatastructlist (const GNOME_Trilobite_Eazel_P
pack->depends = g_list_prepend (pack->depends, dep);
}
}
+
pack->depends = g_list_reverse (pack->depends);
for (j = 0; j < corbapack->breaks._length; j++) {
@@ -568,7 +580,7 @@ GList*
categorydata_list_from_corba_categorystructlist (const GNOME_Trilobite_Eazel_CategoryStructList *corbacategories)
{
GList *categories;
- guint i,j;
+ guint i;
categories = NULL;
@@ -582,17 +594,9 @@ categorydata_list_from_corba_categorystructlist (const GNOME_Trilobite_Eazel_Cat
corbacategory = &(corbacategories->_buffer[i]);
packagelist = &(corbacategory->packages);
- for (j = 0; j < packagelist->_length; j++) {
- PackageData *pack;
- GNOME_Trilobite_Eazel_PackageDataStruct *corbapack;
-
- corbapack = &(packagelist->_buffer[j]);
- pack = packagedata_from_corba_packagedatastruct (corbapack);
- packages = g_list_prepend (packages, pack);
- }
category = categorydata_new ();
category->name = (strlen (corbacategory->name) > 0) ? g_strdup (corbacategory->name) : NULL;
- category->packages = packages;
+ category->packages = packagedata_list_from_corba_packagedatastructlist (packagelist);
categories = g_list_prepend (categories, category);
}
diff --git a/components/services/install/lib/eazel-install-logic.c b/components/services/install/lib/eazel-install-logic.c
index 38dbc9922..9f8083c04 100644
--- a/components/services/install/lib/eazel-install-logic.c
+++ b/components/services/install/lib/eazel-install-logic.c
@@ -20,6 +20,9 @@
* Authors: Eskil Heyn Olsen <eskil@eazel.com>
*/
+/* CVS version 1.41 contains the big chunks of old logic code
+ that got evicted in the last phases of logic2 work */
+
#include "eazel-install-logic.h"
#include "eazel-install-xml-package-list.h"
#include "eazel-install-public.h"
@@ -53,748 +56,9 @@
#include <sys/wait.h>
#endif
-static gboolean eazel_install_do_install_packages (EazelInstall *service,
- GList* packages);
-
-static int eazel_install_start_transaction (EazelInstall *service,
- GList* packages);
-
-static gboolean eazel_install_ensure_deps (EazelInstall *service,
- GList **filenames,
- GList **fails);
-
-static void eazel_uninstall_globber (EazelInstall *service,
- GList **packages,
- GList **failed);
-
-static gboolean eazel_install_download_packages (EazelInstall *service,
- gboolean toplevel,
- GList **packages,
- GList **failed_packages);
-#if 0
-static gboolean eazel_install_check_for_file_conflicts (EazelInstall *service,
- PackageData *pack,
- GList **breaks,
- GList **requires);
-#endif
-static void eazel_install_prune_packages (EazelInstall *service,
- PackageData *pack,
- ...);
-/*
- Checks for pre-existance of all the packages
- */
-static void
-eazel_install_pre_install_packages (EazelInstall *service,
- GList **packages)
-{
- GList *iterator;
- GList *failed_packages = NULL;
-
- for (iterator = *packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- EazelInstallStatus inst_status;
- gboolean skip = FALSE;
-
- inst_status = eazel_install_check_existing_packages (service, pack);
-
- /* If in force mode, install it under all circumstances.
- if not, only install if not already installed in same
- version or up/downgrade is set */
- if (eazel_install_get_force (service) ||
- (eazel_install_get_downgrade (service) && inst_status == EAZEL_INSTALL_STATUS_DOWNGRADES) ||
- (eazel_install_get_update (service) && inst_status == EAZEL_INSTALL_STATUS_UPGRADES) ||
- inst_status == EAZEL_INSTALL_STATUS_NEW_PACKAGE) {
- skip = FALSE;
- } else {
- skip = TRUE;
- }
-
- if (skip) {
- trilobite_debug ("Skipping %s...", pack->name);
-#if 0
- /* Nuke the modifies list again, since we don't want to see them */
- g_list_foreach (pack->modifies,
- (GFunc)packagedata_destroy,
- GINT_TO_POINTER (TRUE));
- g_list_free (pack->modifies);
- pack->modifies = NULL;
-#endif
-
- /* Add it to the list of packages to nuke at the end
- of this function */
- failed_packages = g_list_prepend (failed_packages, pack);
- }
- }
-
- for (iterator = failed_packages; iterator; iterator=g_list_next (iterator)) {
- eazel_install_prune_packages (service,
- (PackageData*)iterator->data,
- packages, NULL);
- }
- g_list_free (failed_packages);
-}
-
-EazelInstallStatus
-ei_install_packages (EazelInstall *service, GList *categories) {
- EazelInstallStatus result;
-
- if (categories == NULL) {
- trilobite_debug (_("Reading the install package list %s"), eazel_install_get_package_list (service));
- categories = parse_local_xml_package_list (eazel_install_get_package_list (service), NULL, NULL);
- }
-
- result = EAZEL_INSTALL_NOTHING;
- if (categories != NULL) {
- /* First, collect all packages in one list */
- GList *packages = categorylist_flatten_to_packagelist (categories);
-
- /* Now download all the packages */
- if (eazel_install_download_packages (service, TRUE, &packages, NULL)) {
-
- /* check for packages that are already installed */
- eazel_install_pre_install_packages (service, &packages);
-
- /* Files downloaded, now install */
- if (eazel_install_do_install_packages (service, packages)) {
- result |= EAZEL_INSTALL_INSTALL_OK;
- }
- }
- }
-
- return result;
-} /* end install_new_packages */
-
-/*
- Download all the packages and keep doing that by recursively
- calling eazel_install_download_packages with package->soft_depends
- */
-static gboolean
-eazel_install_download_packages (EazelInstall *service,
- gboolean toplevel,
- GList **packages,
- GList **failed_packages)
-{
- g_assert_not_reached ();
- return TRUE;
-#if 0
- GList *iterator;
- gboolean result = TRUE;
- GList *remove_list = NULL;
-
- g_assert (packages);
- g_assert (*packages);
-
- for (iterator = *packages; (iterator != NULL) && result; iterator = g_list_next (iterator)) {
- PackageData* package = (PackageData*)iterator->data;
- gboolean fetch_package;
-
- fetch_package = TRUE;
-
- trilobite_debug ("init for %s (%s/%s)", package->name, package->version ? package->version : "NO VERSION",
- toplevel?"TRUE":"FALSE");
- /* if filename in the package is set, but the file
- does not exist, get it anyway */
- if (package->filename) {
- trilobite_debug ("Filename set, and file exists = %d",
- g_file_test (package->filename, G_FILE_TEST_ISFILE));
- if (g_file_test (package->filename, G_FILE_TEST_ISFILE)) {
- /* Don't fetch, but load rpm header and return
- ok */
- fetch_package = FALSE;
- result = TRUE;
- package = eazel_package_system_load_package (service->private->package_system,
- package,
- package->filename,
- PACKAGE_FILL_NO_DIRS_IN_PROVIDES);
- } else {
- /* The file didn't exist, remove the
- leading path and set the filename, plus
- toggle the fetch_package to TRUE */
- g_free (package->filename);
- package->filename = g_strdup (g_basename (package->filename));
- }
- } else if (!eazel_install_get_force (service) && package->version) {
- /* If the package has a version set, check that we don't already have
- the same or newer installed. This is almost the same check as
- in eazel_install_pre_install_package. The reason for two checks is
- - first check before download (if possible)
- - after download, when we for sure have access to the version, check again
- - we do this before do_dependency_check to avoid downloaded soft_deps.
- */
- EazelInstallStatus inst_status;
-
- inst_status = eazel_install_check_existing_packages (service, package);
- if (eazel_install_get_downgrade (service) && inst_status == EAZEL_INSTALL_STATUS_DOWNGRADES) {
- trilobite_debug (_("Will download %s"), package->name);
- /* must download... */
- } else if (inst_status == EAZEL_INSTALL_STATUS_QUO ||
- inst_status == EAZEL_INSTALL_STATUS_DOWNGRADES) {
- /* Nuke the modifies list again, since we don't want to see them */
- g_list_foreach (package->modifies,
- (GFunc)packagedata_destroy,
- GINT_TO_POINTER (TRUE));
- g_list_free (package->modifies);
- package->modifies = NULL;
- /* don't fecth the package */
- fetch_package = FALSE;
- /* Add it to the list of packages to nuke at the end
- of this function */
- remove_list = g_list_prepend (remove_list, package);
- trilobite_debug (_("%s already installed"), package->name);
- }
- }
-
- if (fetch_package) {
- result = eazel_install_fetch_package (service, package);
-
- if (!result) {
- package->status = PACKAGE_CANNOT_OPEN;
- remove_list = g_list_prepend (remove_list, package);
- } else {
-#if 0
- /* If downloaded package has soft_deps,
- fetch them by a recursive call */
- if (package->soft_depends) {
- result = eazel_install_download_packages (service,
- FALSE,
- &package->soft_depends,
- NULL);
- }
-#endif
- }
- }
-
- if (result) {
- package->toplevel = toplevel;
- if (package->source_package) {
- package->status = PACKAGE_SOURCE_NOT_SUPPORTED;
- remove_list = g_list_prepend (remove_list, package);
- }
- if (strlen ("debug")) {
- char *tmp = packagedata_dump (package, TRUE);
- fprintf (stderr, "%s", tmp);
- g_free (tmp);
- }
- }
- }
-
- for (iterator = remove_list; iterator; iterator = g_list_next (iterator)) {
- PackageData *package = (PackageData*)(iterator->data);
- eazel_install_prune_packages (service, package, packages, NULL);
- }
-
- if (failed_packages) {
- (*failed_packages) = remove_list;
- }
-
- return result;
-#endif
-}
-#if 0
-/*
- This function checks all files in pack->provides, and
- checks if another already installed package owns this file.
- returns FALSE is there are no conflicts, and TRUE if there
- are.
-
- If there are conflicts because of a related package,
- this package is added to *requires.
- */
-static gboolean
-eazel_install_check_for_file_conflicts (EazelInstall *service,
- PackageData *pack,
- GList **breaks,
- GList **requires)
-{
- GList *owners;
- GList *iterator;
- /* Set optimism to high */
- gboolean result = FALSE;
-
- g_assert (service);
- g_assert (pack);
- g_assert (requires);
- g_assert (*requires == NULL);
-
- trilobite_debug ("Checking file conflicts for %s", pack->name);
-
- for (iterator = pack->provides; iterator; glist_step (iterator)) {
- char *filename = (char*)iterator->data;
-
- /* many packages will supply some dirs, eg /usr/share/locale/../LC_MESSAGES
- dirs, so don't check those
-
- eazel-install-types
- (packagedata_fill_from_rpm_header) now does not add
- these. This is more safe, as checking the file
- could still cause a conflict, if the file was not
- on the system but two dirs had the same dir
-
- if (g_file_test (filename, G_FILE_TEST_ISDIR)) {
- continue;
- } */
-
- owners = eazel_package_system_query (service->private->package_system,
- service->private->cur_root,
- filename,
- EAZEL_PACKAGE_SYSTEM_QUERY_OWNS,
- PACKAGE_FILL_NO_DIRS_IN_PROVIDES);
- packagedata_list_prune (&owners, pack->modifies, TRUE, TRUE);
-
- if (g_list_length (owners) > 1) {
- GList *pit;
- /* FIXME bugzilla.eazel.com 3511:
- More than one packages owns this file,
- this cannot happen (or should not at least)
- */
- trilobite_debug ("***************************************************");
- trilobite_debug ("More than one package owns the file %s", filename);
- trilobite_debug ("This is filed as bug 2959");
- trilobite_debug ("Try rpm --rebuilddb");
- for (pit = owners; pit; pit = g_list_next (pit)) {
- char *tmp;
- PackageData *owner = (PackageData*)(pit->data);
- tmp = packagedata_get_readable_name (owner);
- trilobite_debug ("a owner is %s", tmp);
- g_free (tmp);
- }
- trilobite_debug ("halting...");
- g_assert_not_reached ();
- } else if (g_list_length (owners) == 1) {
- PackageData *owner = (PackageData*)owners->data;
-
- /* If the package owner is already in the breaks list for the package,
- or in the *requires, continue */
- if (g_list_find_custom (*breaks, owner->name,
- (GCompareFunc)eazel_install_package_name_compare) ||
- g_list_find_custom (*requires, owner->name,
- (GCompareFunc)eazel_install_package_name_compare)) {
- /* trilobite_debug ("already breaking %s", owner->name); */
- gtk_object_unref (GTK_OBJECT (owner));
- owner = NULL;
- continue;
- }
-
- if (strcmp (pack->name, owner->name)) {
- trilobite_debug ("file %s from package %s conflicts with file from package %s",
- filename, pack->name, owner->name);
-
- result = TRUE;
- if (eazel_install_check_if_related_package (service, pack, owner)) {
- trilobite_debug ("Package %s may be related to %s",
- owner->name, pack->name);
- g_free (owner->version);
- owner->version = g_strdup (pack->version);
- (*requires) = g_list_prepend (*requires, owner);
- } else {
- owner->status = PACKAGE_FILE_CONFLICT;
- (*breaks) = g_list_prepend (*breaks, owner);
- }
-
- } else {
- /* else it's the same package and it's okay */
- /* so FREE IT YOU SICK MONKEY! */
- gtk_object_unref (GTK_OBJECT (owner));
- }
- }
- /* free the _simple_query result list */
- g_list_free (owners);
-
-#ifdef EAZEL_INSTALL_SLIM
- /* In the slim, we need to enter the g_main_loop during file check */
- g_main_iteration (FALSE);
-#endif
-
- }
- return result;
-}
-#endif
-
-static gboolean
-eazel_install_do_install_packages (EazelInstall *service,
- GList* packages)
-{
- gboolean rv = TRUE;
- GList* failedfiles = NULL;
-
- if (packages) {
- rv = FALSE;
- eazel_install_ensure_deps (service, &packages, &failedfiles);
- if (g_list_length (packages)) {
- if (eazel_install_start_transaction (service, packages) == 0) {
- rv = TRUE;
- }
- g_list_free (packages);
- }
- }
-
- return rv;
-} /* end install_packages */
-
-static EazelInstallStatus
-uninstall_all_packages (EazelInstall *service,
- GList *categories)
-{
- EazelInstallStatus result = EAZEL_INSTALL_UNINSTALL_OK;
-
- while (categories) {
- CategoryData* cat = categories->data;
- GList *failed;
-
- trilobite_debug (_("Category = %s"), cat->name);
-
- failed = NULL;
- eazel_uninstall_globber (service, &cat->packages, &failed);
-
- if (eazel_install_start_transaction (service, cat->packages) != 0) {
- result = EAZEL_INSTALL_NOTHING;
- }
-
- categories = g_list_next (categories);
- }
- return result;
-}
-
-EazelInstallStatus
-ei_uninstall_packages (EazelInstall *service,
- GList* categories)
-{
- EazelInstallStatus result = EAZEL_INSTALL_NOTHING;
-
- result |= uninstall_all_packages (service, categories);
-
- return result;
-
-} /* end install_new_packages */
-
-
-static GList *
-ei_get_packages_with_mod_flag (GList *packages,
- PackageModification mod)
-{
- GList *it;
- GList *res;
-
- res = NULL;
- for (it = packages; it; it = g_list_next (it)) {
- PackageData *pack;
- pack = (PackageData*)it->data;
- if (pack->modify_status == mod) {
- res = g_list_prepend (res, pack);
- }
- if (pack->soft_depends) {
- res = g_list_concat (res,
- ei_get_packages_with_mod_flag (pack->soft_depends, mod));
- }
- if (pack->modifies) {
- res = g_list_concat (res,
- ei_get_packages_with_mod_flag (pack->modifies, mod));
- }
- }
- return res;
-}
-
-/* Function to prune the uninstall list for elements marked as downgrade */
-static void
-ei_check_uninst_vs_downgrade (GList **inst,
- GList **down)
-{
- GList *it;
- GList *remove;
-
- remove = NULL;
- for (it = *inst; it; it = g_list_next (it)) {
- GList *entry;
- PackageData *pack;
-
- pack = (PackageData*)it->data;
- entry = g_list_find_custom (*down, pack->name, (GCompareFunc)eazel_install_package_name_compare);
- if (entry != NULL) {
- remove = g_list_prepend (remove, it->data);
- }
- }
-
- for (it = remove; it; it = g_list_next (it)) {
- (*inst) = g_list_remove (*inst, it->data);
- }
-}
-
-static void hest (PackageData *pack, char *str) {
- trilobite_debug ("Must %s %s", str, pack->name);
-}
-
-EazelInstallStatus
-ei_revert_transaction (EazelInstall *service,
- GList *packages)
-{
- GList *uninst, *inst, *upgrade, *downgrade;
- CategoryData *cat;
- GList *categories;
- EazelInstallStatus result = EAZEL_INSTALL_NOTHING;
-
- uninst = ei_get_packages_with_mod_flag (packages, PACKAGE_MOD_INSTALLED);
- inst = ei_get_packages_with_mod_flag (packages, PACKAGE_MOD_UNINSTALLED);
- upgrade = ei_get_packages_with_mod_flag (packages, PACKAGE_MOD_DOWNGRADED);
- downgrade = ei_get_packages_with_mod_flag (packages, PACKAGE_MOD_UPGRADED);
-
- ei_check_uninst_vs_downgrade (&uninst, &downgrade);
-
- g_list_foreach (uninst, (GFunc)hest, "uninstall");
- g_list_foreach (inst, (GFunc)hest, "install");
- g_list_foreach (downgrade, (GFunc)hest, "downgrade");
- g_list_foreach (upgrade, (GFunc)hest, "upgrade");
-
- cat = categorydata_new ();
- categories = g_list_prepend (NULL, cat);
-
- if (uninst) {
- eazel_install_set_uninstall (service, TRUE);
- eazel_install_set_downgrade (service, FALSE);
- eazel_install_set_update (service, FALSE);
- cat->packages = uninst;
- result |= ei_uninstall_packages (service, categories);
- }
- if (inst) {
- eazel_install_set_uninstall (service, FALSE);
- eazel_install_set_downgrade (service, FALSE);
- eazel_install_set_update (service, FALSE);
- cat->packages = inst;
- result |= ei_install_packages (service, categories);
- }
- if (downgrade) {
- eazel_install_set_uninstall (service, FALSE);
- eazel_install_set_downgrade (service, TRUE);
- eazel_install_set_update (service, FALSE);
- cat->packages = downgrade;
- result |= ei_install_packages (service, categories);
- }
- if (upgrade) {
- eazel_install_set_uninstall (service, FALSE);
- eazel_install_set_downgrade (service, TRUE);
- eazel_install_set_update (service, TRUE);
- cat->packages = upgrade;
- result |= ei_install_packages (service, categories);
- g_list_foreach (upgrade, (GFunc)gtk_object_unref, NULL);
- }
-
- return result;
-}
-
-
-void
-eazel_install_do_transaction_add_to_transaction (EazelInstall *service,
- PackageData *pack)
-{
- service->private->transaction = g_list_prepend (service->private->transaction,
- pack);
-}
-
-static void
-eazel_install_do_transaction_save_report_helper (xmlNodePtr node,
- GList *packages)
-{
- GList *iterator;
-
- for (iterator = packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack;
- char *tmp;
- pack = (PackageData*)iterator->data;
- switch (pack->modify_status) {
- case PACKAGE_MOD_INSTALLED:
- tmp = g_strdup_printf ("Installed %s", pack->name);
- xmlNewChild (node, NULL, "DESCRIPTION", tmp);
- g_free (tmp);
- break;
- case PACKAGE_MOD_UNINSTALLED:
- tmp = g_strdup_printf ("Uninstalled %s", pack->name);
- xmlNewChild (node, NULL, "DESCRIPTION", tmp);
- g_free (tmp);
- break;
- default:
- break;
- }
- if (pack->modifies) {
- eazel_install_do_transaction_save_report_helper (node, pack->modifies);
- }
- }
-}
-
-static void
-eazel_install_do_transaction_save_report (EazelInstall *service)
-{
- FILE *outfile;
- xmlDocPtr doc;
- xmlNodePtr node, root;
- char *name = NULL;
-
- if (eazel_install_get_transaction_dir (service) == NULL) {
- g_warning ("Transaction directory not set, not storing transaction report");
- }
-
- /* Ensure the transaction dir is present */
- if (! g_file_test (eazel_install_get_transaction_dir (service), G_FILE_TEST_ISDIR)) {
- int retval;
- retval = mkdir (eazel_install_get_transaction_dir (service), 0755);
- if (retval < 0) {
- if (errno != EEXIST) {
- g_warning (_("Could not create transaction directory (%s)! ***\n"),
- eazel_install_get_transaction_dir (service));
- return;
- }
- }
- }
-
- /* Create xml */
- doc = xmlNewDoc ("1.0");
- root = node = xmlNewNode (NULL, "TRANSACTION");
- xmlDocSetRootElement (doc, node);
-
- /* Make a unique name */
- name = g_strdup_printf ("%s/transaction.%lu", eazel_install_get_transaction_dir (service),
- (unsigned long) time (NULL));
- while (g_file_test (name, G_FILE_TEST_ISFILE)) {
- g_free (name);
- sleep (1);
- name = g_strdup_printf ("%s/transaction.%lu",
- eazel_install_get_transaction_dir (service),
- (unsigned long) time (NULL));
- }
-
- trilobite_debug (_("Writing transaction to %s"), name);
-
- /* Open and save */
- outfile = fopen (name, "w");
- xmlAddChild (root, eazel_install_packagelist_to_xml (service->private->transaction, FALSE));
- node = xmlAddChild (node, xmlNewNode (NULL, "DESCRIPTIONS"));
-
- {
- char *tmp;
- tmp = g_strdup_printf ("%lu", (unsigned long) time (NULL));
- xmlNewChild (node, NULL, "DATE", tmp);
- g_free (tmp);
- }
-
- eazel_install_do_transaction_save_report_helper (node, service->private->transaction);
-
- xmlDocDump (outfile, doc);
-
- fclose (outfile);
- g_free (name);
-}
-
-/*
- This checks, that for a given set of packages, no two packages
- contains the same file.
- This is done by filling a hashtable with the files from
- package->provides (which have full pathname) and link to the
- owning package. Before adding a file to the hashtable, lookup the
- file first. If result is non-null, problem...
-
- Did I mention that this function leaks memory like a russian submarine? -robey
- */
-static gboolean
-eazel_install_do_transaction_all_files_check (EazelInstall *service,
- GList **packages)
-{
- g_assert_not_reached ();
- return FALSE;
-#if 0
- gboolean result = TRUE;
- GList *iterator;
- GList *conflicts = NULL; /* PackageRequirements. ->package is the first found package
- that providing a file, ->required is the second file that
- has the same file */
- GHashTable *file_to_pack; /* maps from a filename to a packagedata struct */
-
- if (eazel_install_get_force (service) ||
- eazel_install_get_ignore_file_conflicts (service) ||
- (g_list_length (*packages) == 1 )) {
- trilobite_debug ("not performing file conflict check");
- return result;
- }
-
- file_to_pack = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Check all the packages */
- for (iterator = *packages; iterator; glist_step (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- GList *file_iterator;
- int reported_yet = FALSE;
- int other_conflicts = 0;
-
- /* Check all files provided */
- for (file_iterator = pack->provides; file_iterator; glist_step (file_iterator)) {
- char *fname = (char*)file_iterator->data;
- /* Lookup and check what happens... */
- PackageData *previous_pack = g_hash_table_lookup (file_to_pack,
- fname);
- if (previous_pack) {
- /* Dang, fname is owned by previous_pack but pack also adds it */
- /* The use of reported_yet && other_conflicts is purely for
- debug nicety. It ensures that only one fileconflicts pr
- package is printed, whereas the alternative is eg. 200 */
- if (! reported_yet) {
- trilobite_debug ("conflict, file %s from package %s is also in %s",
- fname,
- pack->name,
- previous_pack->name);
- reported_yet = TRUE;
- } else {
- other_conflicts++;
- }
- if (!g_list_find_custom (conflicts,
- pack,
- (GCompareFunc)eazel_install_requirement_dep_compare)) {
- PackageRequirement *req;
-
- req = packagerequirement_new (previous_pack, pack);
- conflicts = g_list_prepend (conflicts, req);
- }
- } else {
- /* File is ok */
- g_hash_table_insert (file_to_pack,
- fname,
- pack);
- }
- }
- if (other_conflicts) {
- trilobite_debug ("(%d other conflicts from the same package... *sigh*)", other_conflicts);
- }
- }
-
- for (iterator = conflicts; iterator; glist_step (iterator)) {
- PackageRequirement *req = (PackageRequirement*)iterator->data;
-
- result = FALSE;
- /* Need to fail the package here to fully fix bug
- FIXME bugzilla.eazel.com 3374: */
- trilobite_debug ("Conflict between %s and %s", req->package->name, req->required->name);
- req->package->status = PACKAGE_FILE_CONFLICT;
- req->required->status = PACKAGE_FILE_CONFLICT;
- Xpackagedata_add_pack_to_breaks (req->package, req->required);
- eazel_install_prune_packages (service, req->package, packages, NULL);
- }
-
- return result;
-#endif
-}
-
-
-static unsigned long
-get_total_size_of_packages (const GList *packages)
-{
- const GList *iterator;
- unsigned long result = 0;
- for (iterator = packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- result += pack->bytesize;
- }
- return result;
-}
-
/* A GHRFunc to clean
out the name_to_package hash table
-*/
+
static gboolean
eazel_install_clean_name_to_package_hash (char *key,
PackageData *pack,
@@ -803,12 +67,14 @@ eazel_install_clean_name_to_package_hash (char *key,
g_free (key);
return TRUE;
}
+*/
/* This begins the package transaction.
Return value is number of failed packages
*/
-int
+#if 0
+static int
eazel_install_start_transaction (EazelInstall *service,
GList* packages)
{
@@ -856,7 +122,7 @@ eazel_install_start_transaction (EazelInstall *service,
service->private->infoblock [2] = 0;
service->private->infoblock [3] = g_list_length (packages);
service->private->infoblock [4] = 0;
- service->private->infoblock [5] = get_total_size_of_packages (packages);
+ service->private->infoblock [5] = 0;
if (eazel_install_emit_preflight_check (service, packages)) {
/* this makes the primary packages appear before their dependencies. very useful for installs
@@ -876,7 +142,7 @@ eazel_install_start_transaction (EazelInstall *service,
flag);
}
- eazel_install_do_transaction_save_report (service);
+ eazel_install_save_transaction_report (service);
}
g_list_free (service->private->transaction);
@@ -888,166 +154,7 @@ eazel_install_start_transaction (EazelInstall *service,
return res;
} /* end start_transaction */
-
-
-/* Checks if pack depends on dep, by doing a deep tree search */
-static gboolean
-eazel_install_check_if_depends_on (PackageData *pack,
- PackageData *dep)
-{
- gboolean result = FALSE;
- GList *iterator;
-
- for (iterator = pack->soft_depends; !result && iterator; glist_step (iterator)) {
- PackageData *nisse = (PackageData*)iterator->data;
- if (nisse == dep) {
- result = TRUE;
- } else if (eazel_install_check_if_depends_on (nisse, dep)) {
- /* trilobite_debug ("nope, recursing"); */
- result = TRUE;
- }
- }
-
- return result;
-}
-
-/*
- The helper for eazel_install_prune_packages.
- If the package is in "pruned", it has already been marked
- for pruning.
- Otherwise, prune first it's softdepends, then all
- packages that depend on it.
- */
-static void
-eazel_install_prune_packages_helper (EazelInstall *service,
- GList **packages,
- GList **pruned,
- PackageData *pack)
-{
- GList *iterator;
- char *tmp;
-
- g_return_if_fail (pack!=NULL);
- /* If already pruned, abort */
- if (g_list_find (*pruned, pack) || pack->name==NULL) {
- return;
- }
- tmp = packagedata_get_readable_name (pack);
- trilobite_debug (_("Removing package %s (0x%p) %s"),
- tmp,
- pack,
- pack->toplevel ? "(emit fail)" :"()");
- g_free (tmp);
- if (pack->toplevel) {
- /* We only emit signal for the toplevel packages,
- and only delete them. They _destroy function destroys
- the entire dep tree */
- eazel_install_emit_install_failed (service, pack);
- }
- /* Add to list of pruned packages */
- (*pruned) = g_list_prepend (*pruned, pack);
-
- /* Prune all it's soft_deps */
- for (iterator = pack->soft_depends; iterator; iterator = g_list_next (iterator)) {
- PackageData *sub;
- sub = (PackageData*)iterator->data;
- eazel_install_prune_packages_helper (service, packages, pruned, sub);
- }
-
- /* For all packages in "packages", check if they depend on this */
- for (iterator = *packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *super;
-
- super = (PackageData*)iterator->data;
- /* FIXME bugzilla.eazel.com 3542:
- This is the cause of 3542.
- In this specific case, gnome-print is removed from the toplevel and from
- 1st sublevel of soft_deps.
- The problem is, that this g_list_find only looks down one level, and does'nt
- search the entire tree, duh.
- I need a find_custom call that does this the right way */
- if (eazel_install_check_if_depends_on (super, pack)) {
- eazel_install_prune_packages_helper (service, packages, pruned, super);
- }
- }
-}
-
-/*
- Used to remove a package "pack" and all
- packages in "packages" that depends
- on "pack".
-
- To do this, we need the _helper, which gathers
- the stripped files into "pruned". That way, we
- can safely traverse without altering
- the lists during the for loops (as g_list_remove
- will fuck up the for loop).
-
- This may end in a recursive loop if
- the ->soft_depends points to something
- upwards in the dep tree (circular dependency)
-
- First it calls prune_helper for all the given packages,
- at each iteration it removes the pruned (from list "pruned")
- packages.
-
- Finally it deallocates all the pruned packages.
-
-*/
-
-static void
-eazel_install_prune_packages (EazelInstall *service,
- PackageData *pack,
- ...)
-{
- va_list ap;
- GList *pruned;
- GList *iterator;
- GList **packages;
-
- g_return_if_fail (pack!=NULL);
-
- va_start (ap, pack);
-
- pruned = NULL;
- while ( (packages = va_arg (ap, GList **)) != NULL) {
- eazel_install_prune_packages_helper (service,
- packages,
- &pruned,
- pack);
- for (iterator = pruned; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- /* trilobite_debug ("%s pruned", pack->name); */
- (*packages) = g_list_remove (*packages, pack);
- };
- }
-
- /* Note, don't destroy, all packages are destroyed when the
- categories are destroyed
- for (iterator = pruned; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack;
- pack = (PackageData*)iterator->data;
- gtk_object_unref (GTK_OBJECT (pack));
- };
- */
-
- g_list_free (pruned);
-
- va_end (ap);
-}
-#if 0
-static void
-eazel_install_add_to_extras_foreach (char *key, GList *list, GList **extrapackages)
-{
- GList *iterator;
- PackageData *dep;
- for (iterator = list; iterator; iterator = g_list_next (iterator)) {
- dep = (PackageData*)iterator->data;
- (*extrapackages) = g_list_prepend (*extrapackages, dep);
- }
- g_list_free (list);
-}
-#endif
+#endif
/*
This function tests wheter "package" and "dep"
@@ -1128,252 +235,22 @@ eazel_install_check_if_related_package (EazelInstall *service,
return result;
}
-static gboolean
-eazel_install_fetch_dependencies (EazelInstall *service,
- GList **packages,
- GList **extrapackages,
- GList **failedpackages,
- GList *requirements)
-{
- g_assert_not_reached ();
- return FALSE;
-#if 0
- GList *iterator;
- /* Contains the packages downloaded when handling the list of requirements */
- GList *extras_in_this_batch = NULL;
- GHashTable *extras;
- gboolean fetch_result;
-
- extras = g_hash_table_new (g_str_hash, g_str_equal);
- fetch_result = FALSE;
-
- trilobite_debug ("%d requirements to be fetched/resolved", g_list_length (requirements));
- for (iterator = requirements; iterator; glist_step (iterator)) {
- PackageRequirement *req = (PackageRequirement*)iterator->data;
- PackageData *pack = req->package;
- PackageData *dep = req->required;
-
- /* Check to see if the package system happened to file a requirement
- for a package that was also failed... */
- if (g_list_find_custom (*failedpackages,
- pack,
- (GCompareFunc)eazel_install_package_compare)) {
- char *tmp;
- tmp = packagedata_get_readable_name (pack);
- trilobite_debug ("%s already failed, will not download it's requirements", tmp);
- g_free (tmp);
- gtk_object_unref (GTK_OBJECT (dep));
- continue;
- }
-
- /* We use the unknown status later, to see if
- we should set it or not */
- dep->status = PACKAGE_UNKNOWN_STATUS;
-
- /* Emit the signal here, since then we won't have to make that
- call in for every package system (when I say every, we know
- I mean "both"...) */
- eazel_install_emit_dependency_check_pre_ei2 (service, pack, dep);
- packagedata_add_pack_to_soft_depends (pack, dep);
-
- fetch_result = eazel_install_fetch_package (service, dep);
-
- if (fetch_result) {
- if (dep->source_package) {
- dep->status = PACKAGE_SOURCE_NOT_SUPPORTED;
- fetch_result = FALSE;
- }
- }
-
- if (fetch_result) {
- /* If the package we just downloaded was already in packages,
- but we just had a dependency conflict, we're in the funky case,
- were pacakge foo is not installed. But the dependecy stuff has caused
- it to be downloaded in version x.y, and later in v.w. This means that
- the first conflict (causing x.y to be downloaded) now happens again.
- */
- if (g_list_find_custom (*packages,
- dep->name,
- (GCompareFunc)eazel_install_package_name_compare)) {
- GList *pack_entry;
-
- pack_entry = g_list_find_custom (*packages,
- dep,
- (GCompareFunc)eazel_install_package_other_version_compare);
- trilobite_debug ("Circular dependency %s-%s-%s at 0x%p",
- dep->name, dep->version, dep->minor, dep);
-
- if (pack_entry) {
- PackageData *evil_package = packagedata_copy ((PackageData*)(pack_entry->data), FALSE);
- Xpackagedata_add_pack_to_breaks (dep, evil_package);
- trilobite_debug ("Circular dependency caused by %s-%s-%s at 0x%p",
- evil_package->name,
- evil_package->version,
- evil_package->minor,
- evil_package);
- evil_package->status = PACKAGE_CIRCULAR_DEPENDENCY;
- } else {
- trilobite_debug ("This is Bad: I cannot set the funky break list");
- }
- dep->status = PACKAGE_CIRCULAR_DEPENDENCY;
- fetch_result = FALSE;
- }
- }
-
- if (fetch_result) {
- EazelInstallStatus inst_status;
- /* This sets the dep->modifies and checks for a funky case.
- This case is sort of like the one above.
- If the call returns 0, the following must have happened ;
- We had a dependency saying that foo required bar-x.y.
- So we download bar and now discover that bar is already installed
- in the exact same version (x.y). So that means, another
- dependency solving caused us to up/downgrade bar to another
- version, and the following dep check then caused a
- conflict indicating that we should *not* do this up/downgrade.
-
- Solution: fail the downgraded package
-
- I assume the packages have the same name...
- */
- inst_status = eazel_install_check_existing_packages (service, dep);
- if (inst_status == EAZEL_INSTALL_STATUS_QUO) {
- GList *pack_entry;
-
- trilobite_debug ("package %s required %s", pack->name, dep->name);
- trilobite_debug ("This is because some other package was downloaded");
- trilobite_debug ("and crushed this, since %s is already installed", dep->name);
-
- /* Use name compare here, as we expect the package to have the same name */
- pack_entry = g_list_find_custom (*packages,
- dep->name,
- (GCompareFunc)eazel_install_package_name_compare);
- if (pack_entry) {
- /* FIXME bugzilla.eazel.com
- I suspect that adding this to adding evil_package to pack's breaks
- might yield a more pleasant tree */
- PackageData *evil_package = (PackageData*)pack_entry->data;
- Xpackagedata_add_pack_to_breaks (evil_package, dep);
- evil_package->status = PACKAGE_BREAKS_DEPENDENCY;
- } else {
- trilobite_debug ("This is also Bad: I cannot set the funky break list");
- }
- dep->status = PACKAGE_CIRCULAR_DEPENDENCY;
- fetch_result = FALSE;
- } else if (eazel_install_get_downgrade (service)==FALSE &&
- inst_status == EAZEL_INSTALL_STATUS_DOWNGRADES) {
- /* Bad, we're downgrading but not allowed to downgrade */
- fetch_result = FALSE;
- } else if (eazel_install_get_update (service)==FALSE &&
- inst_status == EAZEL_INSTALL_STATUS_UPGRADES) {
- /* Bad, we're upgrading but not allowed to upgrade */
- fetch_result = FALSE;
- }
-
- }
-
- if (fetch_result) {
- /* if it succeeds, add to a list of extras for this package
- We cannot just put it into extrapackages, as a later dep
- might fail, and than we have to fail the package */
- GList *extralist;
-
- /* Check if a previous requirement download solved this
- Note, we don't check till after download, since only a download
- will reveal the packagename in case we need to download
- using fetch_package using the pack->provides.
- This is a paranoia check in addition to a check done
- in do_dependency_check, since a dep check might say
- that we require two files that are provided by the same
- package, and we only want to get the package once.
- Eg. nautilus requires libgconf-gtk-1.so and libgconf-1.so,
- both provided by gconf, so we fetch gconf twice */
- if (g_list_find_custom (extras_in_this_batch,
- dep,
- (GCompareFunc)eazel_install_package_compare)) {
- trilobite_debug ("already handled %s", dep->name);
- packagedata_remove_soft_dep (dep, pack);
- dep = NULL;
- continue;
- }
-
- /* This maintains a list of extra packages for
- a package. So when a requirement D for package A fails,
- and we've already downloaded B & C for A,
- we can easily find B & D and remove them */
- extralist = g_hash_table_lookup (extras, pack->name);
- extralist = g_list_append (extralist, dep);
- g_hash_table_insert (extras, pack->name, extralist);
-
- /* This list contains all the packages added in this call
- to fetch_rpm_dependencies. It's used in the initial check,
- to avoid that multiple requests for a file results in
- multiple downloads */
- extras_in_this_batch = g_list_prepend (extras_in_this_batch, dep);
-
- pack->status = PACKAGE_PARTLY_RESOLVED;
- } else {
- /*
- If it fails
- 1) remove it from the extras hashtable for the package,
- thereby ensuring the fetched packages before the fail aren't added
- 2) add the package to the list of stuff to remove (deleting it
- immediately from packages will cause
- eazel_install_match_package_data_from_rpm_conflict
- to return zero. This is fine if we then just do a continue, but
- this way, we get all the missing deps into pack->soft_depends
- 3) add to list of failed packages
- */
- GList *extralist;
-
- pack->status = PACKAGE_DEPENDENCY_FAIL;
- if (dep->status == PACKAGE_UNKNOWN_STATUS) {
- dep->status = PACKAGE_CANNOT_OPEN;
- }
-
- trilobite_debug ("Fetching %s failed, status %s/%s",
- packagedata_get_readable_name (dep),
- packagedata_status_enum_to_str (dep->status),
- packagedata_modstatus_enum_to_str (dep->modify_status));
-
- if (!eazel_install_get_force (service)) {
- /* Remove the extra packages for this package */
- extralist = g_hash_table_lookup (extras, pack->name);
- /* Remove all the extras from the soft_deps (is this what we want ?) */
- g_list_foreach (extralist, (GFunc)packagedata_remove_soft_dep, pack);
- g_list_free (extralist);
- g_hash_table_remove (extras, pack->name);
-
- /* Don't add it to failedpackages more than once */
- if (g_list_find (*failedpackages, pack) == NULL) {
- (*failedpackages) = g_list_prepend (*failedpackages, pack);
- }
- (*packages) = g_list_remove (*packages, pack);
-
- /* Don't process anymore */
- break;
- }
- }
- }
-
- /* iterate over all the lists in extras and add to extrapackages */
- g_hash_table_foreach (extras, (GHFunc)eazel_install_add_to_extras_foreach, extrapackages);
- g_hash_table_destroy (extras);
- g_list_free (extras_in_this_batch);
-
- if (*failedpackages) {
- return FALSE;
- } else {
- return TRUE;
- }
-#endif
-}
-
static void
-dump_one_package (PackageData *pack, char *prefix)
+dump_one_package (GtkObject *foo, char *prefix)
{
char *softprefix, *modprefix, *breakprefix;
char *packname;
+ PackageData *pack = NULL;
+
+ if (IS_PACKAGEDATA (foo)) {
+ pack = PACKAGEDATA (foo);
+ } else if (IS_PACKAGEBREAKS (foo)) {
+ pack = packagebreaks_get_package (PACKAGEBREAKS (foo));
+ } else if (IS_PACKAGEDEPENDENCY (foo)) {
+ pack = PACKAGEDEPENDENCY (foo)->package;
+ } else {
+ g_assert_not_reached ();
+ }
if (pack->name == NULL) {
if (pack->provides && pack->provides->data) {
@@ -1382,20 +259,20 @@ dump_one_package (PackageData *pack, char *prefix)
packname = g_strdup ("[mystery package]");
}
} else {
- packname = g_strdup_printf ("%s-%s-%s", pack->name, pack->version, pack->minor);
+ packname = packagedata_get_readable_name (pack);
}
- trilobite_debug ("%s%s (stat %s/%s), 0x%08X",
+ trilobite_debug ("%s%s (stat %s/%s), %p",
prefix, packname,
packagedata_status_enum_to_str (pack->status),
packagedata_modstatus_enum_to_str (pack->modify_status),
- (unsigned int)pack);
+ pack);
g_free (packname);
softprefix = g_strdup_printf ("%s (s) ", prefix);
breakprefix = g_strdup_printf ("%s (b) ", prefix);
modprefix = g_strdup_printf ("%s (m) ", prefix);
- g_list_foreach (pack->soft_depends, (GFunc)dump_one_package, softprefix);
+ g_list_foreach (pack->depends, (GFunc)dump_one_package, softprefix);
g_list_foreach (pack->modifies, (GFunc)dump_one_package, modprefix);
g_list_foreach (pack->breaks, (GFunc)dump_one_package, breakprefix);
g_free (softprefix);
@@ -1404,22 +281,6 @@ dump_one_package (PackageData *pack, char *prefix)
}
static void
-dump_packages_foreach (PackageData *pack, gpointer unused)
-{
- if (pack->toplevel) {
- dump_one_package (pack, "");
- }
-}
-
-void
-dump_packages (GList *packages)
-{
- trilobite_debug ("##### PACKAGE TREE #####");
- g_list_foreach (packages, (GFunc)dump_packages_foreach, NULL);
- trilobite_debug ("----- end -----");
-}
-
-static void
print_package_list (char *str, GList *packages, gboolean show_deps)
{
GList *iterator;
@@ -1469,245 +330,12 @@ print_package_list (char *str, GList *packages, gboolean show_deps)
}
}
-/*
- Helperfunction to create PackageRequirements for fileconflicts. Should be
- used for packagesystems that don't do this (eg. RPM) */
-static void
-eazel_install_do_file_conflict_check (EazelInstall *service,
- GList **packages,
- GList **failedpackages,
- GList **requirements)
+static int
+compare_break_to_package_by_name (PackageBreaks *breakage, PackageData *pack)
{
- g_assert_not_reached ();
-#if 0
- GList *iterator;
- GList *tmp_failed = NULL;
-
- if (eazel_install_get_ignore_file_conflicts (service) ||
- eazel_install_get_force (service)) {
- trilobite_debug ("not performing file conflict check");
- }
-
- /* Now do file conflicts on all packages */
- for (iterator = *packages; iterator; glist_step (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- GList *required = NULL;
+ PackageData *broken_package = packagebreaks_get_package (breakage);
- /* If we haven't tested conflicts yet */
- if (pack->conflicts_checked == FALSE) {
- GList *breaks = NULL;
- pack->conflicts_checked = TRUE;
- if (eazel_install_check_for_file_conflicts (service, pack, &breaks, &required)) {
- if (required) {
- /* Create PackageRequirements for all the requirements */
- GList *reqiterator;
- for (reqiterator = required;reqiterator;glist_step (reqiterator)) {
- PackageData *required_pack = (PackageData*)reqiterator->data;
- if (g_list_find_custom (*packages,
- required_pack->name,
- (GCompareFunc)eazel_install_package_name_compare)) {
- trilobite_debug ("but we'e updating it (requirement)");
- /* gtk_object_unref (GTK_OBJECT (broken_package)); */
- } else {
- PackageRequirement *req;
- req = packagerequirement_new (pack, required_pack);
- (*requirements) = g_list_prepend (*requirements, req);
- }
- }
- }
- if (breaks) {
- GList *break_iterator;
- gboolean fail_it = FALSE;
- for (break_iterator = breaks; break_iterator; glist_step (break_iterator)) {
- PackageData *broken_package = (PackageData*)break_iterator->data;
- trilobite_debug ("breaking %s", broken_package->name);
- if (g_list_find_custom (*packages,
- broken_package->name,
- (GCompareFunc)eazel_install_package_name_compare)) {
- trilobite_debug ("but we're updating it");
- /* gtk_object_unref (GTK_OBJECT (broken_package)); */
- } else {
- fail_it = TRUE;
- Xpackagedata_add_pack_to_breaks (pack, broken_package);
- }
- }
- if (fail_it) {
- tmp_failed = g_list_prepend (tmp_failed, pack);
- }
- }
- } else {
- /* No file conflicts */
- }
- }
- }
-
- /* Now clean up */
- for (iterator = tmp_failed; iterator; glist_step (iterator)) {
- PackageData *cpack = (PackageData*)(iterator->data);
- (*failedpackages) = g_list_prepend (*failedpackages, cpack);
- (*packages) = g_list_remove (*packages, cpack);
- }
-#endif
-}
-
-/*
- Use package system to do the dependency check
- */
-static void
-eazel_install_do_dependency_check (EazelInstall *service,
- GList **packages,
- GList **failedpackages,
- GList **requirements)
-{
- eazel_install_do_rpm_dependency_check (service,
- packages,
- failedpackages,
- requirements);
- /* RPM's depCheck doens't do fileconflicts, so we do
- them ourselves */
- eazel_install_do_file_conflict_check (service,
- packages,
- failedpackages,
- requirements);
-}
-
-/*
- Given a glist of PackageData's, ensure_deps_are_fetched checks deps
- for them all, if deps fail, fetch the depency and add to packages.
- Returns FALSE if outfiles was set, TRUE is all dependencies were satisfied.
- If a dep could not be found, that name is added to fails)
- */
-static gboolean
-eazel_install_ensure_deps (EazelInstall *service,
- GList **packages,
- GList **failedpackages)
-{
- GList *extrapackages = NULL; /* This list contains packages that were added to "packages" */
- gboolean result;
- GList *requirements = NULL; /* This list contains the PackageRequirements for the dependecy failures */
-
- g_return_val_if_fail (packages != NULL, TRUE);
- g_return_val_if_fail (*packages != NULL, TRUE);
-
- g_return_val_if_fail (g_list_length (*packages)>=1, FALSE);
- result = TRUE;
-
- trilobite_debug ("Into eazel_install_ensure_deps");
-
- /* First we load headers and prepare them.
- The datastructures depend on the packagesystem,
- and are places in service->private->packsys.
- */
-
- eazel_install_do_dependency_check (service,
- packages,
- failedpackages,
- &requirements);
-
- if (requirements != NULL) {
- GList *iterator;
-
- extrapackages = NULL;
-
- /* For all the packages, set state to partly_resolved. */
- for (iterator=*packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack;
- pack = (PackageData*)iterator->data;
- pack->status = PACKAGE_PARTLY_RESOLVED;
- }
-
- trilobite_debug ("%d dependency failure(s)", g_list_length (requirements));
-
- /* Fetch the needed stuff.
- "extrapackages" gets the new packages added,
- packages in "failedpackages" are packages moved from
- "packages" that could not be resolved. */
- eazel_install_fetch_dependencies (service,
- packages,
- &extrapackages,
- failedpackages,
- requirements);
-
- /* Delete the PackageRequirements.
- Note, that we just need to free the structure, both elements
- are kept, req->package in extrapackages or failedpackages and
- req->required will be in req->package's breaks/soft_depends.
- */
- g_list_foreach (requirements, (GFunc)g_free, NULL);
- g_list_free (requirements);
-
- /* Some debug printing */
- dump_packages (*packages);
- print_package_list ("Packages that were fetched", extrapackages, FALSE);
- print_package_list ("Packages that failed", *failedpackages, TRUE);
- } else {
- GList *iterator;
-
- /* Deps are fine, set all packages to resolved */
- for (iterator=*packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack;
- pack = (PackageData*)iterator->data;
- pack->status = PACKAGE_RESOLVED;
- }
- trilobite_debug (_("Dependencies appear ok"));
-
- if (!eazel_install_do_transaction_all_files_check (service, packages)) {
- trilobite_debug (_("But there are file conflicts"));
- /* Now recurse into eazel_install_ensure_deps with
- the new "packages" list */
- eazel_install_ensure_deps (service, packages, failedpackages);
- } else {
- trilobite_debug ("Dependencies still appear ok");
- }
-
- }
-
- /* If there was failedpackages, prune them from the tree
- and the "extrapackages".
- We need to strip from "extrapackages" as well, since :
- while installing A & B, C was added for A, D was
- added for B but B also needs E (but not found). Therefore
- we strip D from "extrapackages" and B is stripped
- from "packages". Keeping D around would
- install a non-needed package
- */
- if (*failedpackages) {
- GList *iterator;
-
- for (iterator = *failedpackages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack;
- pack = (PackageData*)iterator->data;
- trilobite_debug ("calling prune on %s", pack->name);
- eazel_install_prune_packages (service, pack, packages,
- &extrapackages, NULL);
- }
- }
- /* If there were conflicts, we'll have called fetch_dependencies and might
- have downloaded extra packages. So we have to recurse and process these */
- if (extrapackages) {
- GList *iterator;
-
- /* Add to "packages" */
- for (iterator = extrapackages; iterator; iterator = g_list_next (iterator)) {
- (*packages) = g_list_append (*packages, iterator->data);
- }
- g_list_free (extrapackages);
-
- /* Now recurse into eazel_install_ensure_deps with
- the new "packages" list */
- eazel_install_ensure_deps (service, packages, failedpackages);
-
- /* Now remove the packages that failed from "packages"
- and copy them into "failedpackages". */
- for (iterator = *failedpackages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack;
- pack = (PackageData*)iterator->data;
- (*packages) = g_list_remove (*packages, pack);
- }
- }
- dump_packages (*packages);
-
- return result;
+ return eazel_install_package_compare (broken_package, pack);
}
/* This traverses upwards in the deptree from the initial list, and adds
@@ -1742,43 +370,48 @@ eazel_uninstall_upward_traverse (EazelInstall *service,
GList *matches = NULL;
GList *match_iterator;
GList *tmp_breaks = NULL;
- GList *break_iterator = NULL;
-
- trilobite_debug ("checking reqs by %s", rpmname_from_packagedata (pack));
+ GList *b_iterator = NULL;
+
+ /* Get the packages required by pack */
+ trilobite_debug ("checking reqs by %p %s", pack, rpmname_from_packagedata (pack));
matches = eazel_package_system_query (service->private->package_system,
service->private->cur_root,
pack,
EAZEL_PACKAGE_SYSTEM_QUERY_REQUIRES,
- PACKAGE_FILL_NO_DIRS_IN_PROVIDES);
- packagedata_list_prune (&matches, *packages, TRUE, TRUE);
+ PACKAGE_FILL_NO_DIRS_IN_PROVIDES | PACKAGE_FILL_NO_DEPENDENCIES);
+ /* For all of them, mark as a break conflict */
for (match_iterator = matches; match_iterator; match_iterator = g_list_next (match_iterator)) {
PackageData *requiredby = (PackageData*)match_iterator->data;;
requiredby->status = PACKAGE_DEPENDENCY_FAIL;
pack->status = PACKAGE_BREAKS_DEPENDENCY;
- trilobite_debug ("logic.c: %s requires %s", requiredby->name, pack->name);
+ trilobite_debug ("logic.c: %p %s requires %p %s",
+ requiredby, requiredby->name,
+ pack, pack->name);
- /* If we're already marked it as breaking, go on
- if (g_list_find_custom (*breaks, (gpointer)requiredby->name,
- (GCompareFunc)eazel_install_package_name_compare)) {
- trilobite_debug ("skip %s", requiredby->name);
- gtk_object_unref (GTK_OBJECT (requiredby));
- requiredby = NULL;
+ /* If the broken package is in packages, just continue */
+ if (g_list_find_custom (*packages, requiredby,
+ (GCompareFunc)eazel_install_package_compare)) {
+ trilobite_debug ("skip %p %s", requiredby, requiredby->name);
continue;
}
- */
- /* Guess not, mark it as breaking (and that pack is the offender */
+ /* only add to breaks if it's a new breakage */
+ if (g_list_find_custom (*breaks, (gpointer)requiredby,
+ (GCompareFunc)compare_break_to_package_by_name)) {
+ (*breaks) = g_list_prepend ((*breaks), requiredby);
+ }
+
+ /* Create a FeatureMissing breakage */
{
PackageFeatureMissing *breakage = packagefeaturemissing_new ();
packagebreaks_set_package (PACKAGEBREAKS (breakage), requiredby);
packagedata_add_to_breaks (pack, PACKAGEBREAKS (breakage));
- gtk_object_unref (GTK_OBJECT (requiredby));
+ gtk_object_unref (GTK_OBJECT (breakage));
}
- (*breaks) = g_list_prepend ((*breaks), requiredby);
- /* If the package has not been failed yet (and is a toplevel),
+ /* If the pac has not been failed yet (and is a toplevel),
fail it */
if (!g_list_find_custom (*failed, (gpointer)pack->name,
(GCompareFunc)eazel_install_package_name_compare) &&
@@ -1786,18 +419,22 @@ eazel_uninstall_upward_traverse (EazelInstall *service,
(*failed) = g_list_prepend (*failed, pack);
}
}
- /* fre the list structure from _simple_query */
+ g_list_foreach (matches, (GFunc)gtk_object_unref, NULL);
g_list_free (matches);
-
+
+ /* Now check the packages that broke, this is where eg. uninstalling
+ glib begins to take forever */
if (*breaks) {
eazel_uninstall_upward_traverse (service, breaks, failed, &tmp_breaks);
}
- for (break_iterator = tmp_breaks; break_iterator; break_iterator = g_list_next (break_iterator)) {
- (*breaks) = g_list_prepend ((*breaks), break_iterator->data);
+ /* Add the result from the recursion */
+ for (b_iterator = tmp_breaks; b_iterator; b_iterator = g_list_next (b_iterator)) {
+ (*breaks) = g_list_prepend ((*breaks), b_iterator->data);
}
}
+ /* Remove the failed packages */
for (iterator = *failed; iterator; iterator = g_list_next (iterator)) {
(*packages) = g_list_remove (*packages, iterator->data);
}
@@ -1965,126 +602,3 @@ eazel_uninstall_downward_traverse (EazelInstall *service,
trilobite_debug ("out eazel_uninstall_downward_traverse");
}
-
-static void
-eazel_uninstall_check_for_install (EazelInstall *service,
- GList **packages,
- GList **failed)
-{
- GList *iterator;
- GList *remove = NULL;
- GList *result = NULL;
-
- trilobite_debug ("in eazel_uninstall_check_for_install");
- g_assert (packages);
- trilobite_debug ("g_list_length (*packages) = %d", g_list_length (*packages));
- for (iterator = *packages; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- GList *matches;
-
- matches = eazel_package_system_query (service->private->package_system,
- service->private->cur_root,
- pack->name,
- EAZEL_PACKAGE_SYSTEM_QUERY_MATCHES,
- PACKAGE_FILL_NO_TEXT | PACKAGE_FILL_NO_DEPENDENCIES | PACKAGE_FILL_NO_DIRS_IN_PROVIDES);
- /* If it's installed, continue */
- if (matches) {
- GList *match_it;
- gboolean any = FALSE;
- for (match_it = matches; match_it; match_it = g_list_next (match_it)) {
- PackageData *matched = (PackageData*)match_it->data;
- if (eazel_install_package_matches_versioning (matched,
- pack->version,
- pack->minor,
- EAZEL_SOFTCAT_SENSE_EQ)) {
- matched->toplevel = TRUE;
- /* mark that at least one matched */
- any = TRUE;
- result = g_list_prepend (result, matched);
- } else {
- gtk_object_unref (GTK_OBJECT (matched));
- }
-
- }
- if (!any) {
- pack->status = PACKAGE_CANNOT_OPEN;
- remove = g_list_prepend (remove, pack);
- }
- g_list_free (matches);
- continue;
- } else {
- pack->status = PACKAGE_CANNOT_OPEN;
- remove = g_list_prepend (remove, pack);
- }
- }
-
- for (iterator = remove; iterator; iterator=g_list_next (iterator)) {
- (*packages) = g_list_remove (*packages, iterator->data);
- (*failed) = g_list_prepend (*failed, iterator->data);
- }
- g_list_free (remove);
- remove = NULL;
-
- trilobite_debug ("g_list_length (*packages) = %d", g_list_length (*packages));
- trilobite_debug ("g_list_length (result) = %d", g_list_length (result));
-
- g_list_foreach (*packages, (GFunc)gtk_object_unref, NULL);
- g_list_free (*packages);
- (*packages) = result;
-
- trilobite_debug ("out eazel_uninstall_check_for_install");
-}
-
-/* Calls the upward and downward traversal */
-static void
-eazel_uninstall_globber (EazelInstall *service,
- GList **packages,
- GList **failed)
-{
- GList *iterator;
- GList *tmp;
-
- /*
- call upward with packages
- call downward with packages and &tmp
- add all from &tmp to packages
- */
-
- trilobite_debug ("in eazel_uninstall_globber");
-
- tmp = NULL;
-
- eazel_uninstall_check_for_install (service, packages, failed);
- for (iterator = *failed; iterator; iterator = g_list_next (iterator)) {
- trilobite_debug ("not installed %s", ((PackageData*)iterator->data)->name);
- eazel_install_emit_uninstall_failed (service, (PackageData*)iterator->data);
- }
-
- /* If there are still packages and we're not forcing,
- do upwards traversel */
- if (*packages && !eazel_install_get_force (service)) {
- eazel_uninstall_upward_traverse (service, packages, failed, &tmp);
- print_package_list ("FAILED", *failed, TRUE);
- for (iterator = *failed; iterator; iterator = g_list_next (iterator)) {
- PackageData *pack = (PackageData*)iterator->data;
- trilobite_debug ("failed %s", pack->name);
- dump_one_package (pack, "");
- eazel_install_emit_uninstall_failed (service, pack);
- }
- g_list_free (tmp);
- }
-
-/*
- I've disabled downwards traverse untill it's done.
-
- tmp = NULL;
- eazel_uninstall_downward_traverse (service, packages, failed, &tmp);
- for (iterator = tmp; iterator; iterator = g_list_next (iterator)) {
- g_message ("also doing %s", ((PackageData*)iterator->data)->name);
- (*packages) = g_list_prepend (*packages, iterator->data);
- }
- g_list_free (tmp);
-*/
-
- trilobite_debug ("out eazel_uninstall_glob");
-}
diff --git a/components/services/install/lib/eazel-install-logic.h b/components/services/install/lib/eazel-install-logic.h
index 597f24fdf..4255c9a51 100644
--- a/components/services/install/lib/eazel-install-logic.h
+++ b/components/services/install/lib/eazel-install-logic.h
@@ -33,17 +33,6 @@
#include "eazel-install-public.h"
#include <eazel-package-system.h>
-EazelInstallOperationStatus ei_install_packages (EazelInstall *service, GList *categories);
-EazelInstallOperationStatus ei_uninstall_packages (EazelInstall *service, GList *categories);
-EazelInstallOperationStatus ei_revert_transaction (EazelInstall *service, GList *packages);
-
-gboolean eazel_install_prepare_package_system (EazelInstall *service);
-gboolean eazel_install_free_package_system (EazelInstall *service);
-
-unsigned long eazel_install_get_total_size_of_packages (EazelInstall *service,
- const GList *packages);
-void eazel_install_do_transaction_add_to_transaction (EazelInstall *service,
- PackageData *pack);
gboolean eazel_install_check_if_related_package (EazelInstall *service,
PackageData *package,
PackageData *dep);
diff --git a/components/services/install/lib/eazel-install-logic2.c b/components/services/install/lib/eazel-install-logic2.c
index 7616e99b5..d01e554e9 100644
--- a/components/services/install/lib/eazel-install-logic2.c
+++ b/components/services/install/lib/eazel-install-logic2.c
@@ -21,6 +21,7 @@
* Robey Pointer <robey@eazel.com>
*/
+#include "eazel-install-logic.h"
#include "eazel-install-logic2.h"
#include "eazel-install-public.h"
#include "eazel-install-private.h"
@@ -84,7 +85,7 @@ dump_tree_helper (GList *packages, char *indent, GList *path)
pack->eazel_id,
(pack->fillflag & MUST_HAVE) ? "filled" : "not filled",
(pack->status == PACKAGE_CANNOT_OPEN) ? " but failed" : "",
- pack->md5);
+ pack->toplevel ? "TOP":"");
tmp = g_strdup_printf ("%s ", indent);
if (g_list_find (path, pack)) {
trilobite_debug ("%s... %p %s recurses ..", indent, pack, pack->name);
@@ -155,7 +156,9 @@ check_md5_on_files (EazelInstall *service,
trilobite_debug ("No MD5 available for %s", pack->name);
}
}
+
g_list_free (flat_packages);
+ eazel_install_unlock_tmp_dir (service);
return result;
}
@@ -685,6 +688,16 @@ is_satisfied (EazelInstall *service,
return FALSE;
}
+ /* If the dependency has a version, but no sense, something is terribly
+ wrong with the xml */
+#if EI2_DEBUG & 0x4
+ if (dep->version && dep->sense == 0) {
+ trilobite_debug ("I'm going to die now, because softcat is making no sense");
+ trilobite_debug ("Or rather, the xml returned a invalid dependency sense");
+ }
+#endif
+ if (dep->version) { g_assert (dep->sense!=0); }
+
sense_str = eazel_softcat_sense_flags_to_string (dep->sense);
#if EI2_DEBUG & 0x4
trilobite_debug ("is_satisfied? %p %s %s %s",
@@ -856,10 +869,27 @@ check_dependencies_foreach (PackageData *package,
for (iterator = package->depends; iterator; iterator = g_list_next (iterator)) {
PackageDependency *dep = PACKAGEDEPENDENCY (iterator->data);
- if (is_satisfied (service, dep)) {
+
+ if (dep->package->name && strcmp (dep->package->name, package->name)==0) {
+ char *name_a, *name_b;
+
+ name_a = packagedata_get_readable_name (package);
+ name_b = packagedata_get_readable_name (dep->package);
+
+ g_warning ("Possible inconsistency!");
+ g_warning ("%s depends on %s", name_a, name_b);
+
+ g_free (name_a);
+ g_free (name_b);
+
+ package->status = PACKAGE_INVALID;
remove = g_list_prepend (remove, dep);
} else {
- eazel_install_emit_dependency_check (service, package, dep);
+ if (is_satisfied (service, dep)) {
+ remove = g_list_prepend (remove, dep);
+ } else {
+ eazel_install_emit_dependency_check (service, package, dep);
+ }
}
}
@@ -975,6 +1005,7 @@ check_tree_helper (EazelInstall *service,
pack_update->status = PACKAGE_PARTLY_RESOLVED;
remove = g_list_prepend (remove, breakage);
pack->status = PACKAGE_PARTLY_RESOLVED;
+ pack_update->toplevel = TRUE;
} else {
#if EI2_DEBUG & 0x4
trilobite_debug ("%s still has conflict", pack_update->name);
@@ -1584,7 +1615,7 @@ eazel_install_get_total_size_of_packages (EazelInstall *service,
return result;
}
-static void
+static gboolean
execute (EazelInstall *service,
GList *packages,
EazelPackageSystemOperation op,
@@ -1592,6 +1623,7 @@ execute (EazelInstall *service,
{
TrilobiteRootHelper *root_helper;
GList *flat_packages;
+ gboolean result = FALSE;
flat_packages = flatten_packagedata_dependency_tree (packages);
@@ -1603,6 +1635,8 @@ execute (EazelInstall *service,
flags |= EAZEL_PACKAGE_SYSTEM_OPERATION_TEST;
}
+ eazel_install_init_transaction (service);
+
/* Init the hack var to emit the old style progress signals */
service->private->infoblock [0] = 0;
service->private->infoblock [1] = 0;
@@ -1632,13 +1666,15 @@ execute (EazelInstall *service,
break;
}
+ if (service->private->failed_packages == NULL) {
+ eazel_install_save_transaction_report (service);
+ result = TRUE;
+ }
g_list_free (flat_packages);
+
+ return result;
}
-/***********************************************************************************/
-
-/* These are the methods exposed to the the rest of the service object */
-
static void
install_packages_helper (EazelInstall *service,
GList **packages,
@@ -1667,6 +1703,13 @@ install_packages_helper (EazelInstall *service,
}
static void
+set_toplevel (PackageData *package,
+ EazelInstall *service)
+{
+ package->toplevel = TRUE;
+}
+
+static void
expand_package_suites (EazelInstall *service, GList **packages)
{
GList *iter, *newlist, *sublist;
@@ -1696,13 +1739,287 @@ expand_package_suites (EazelInstall *service, GList **packages)
*packages = newlist;
}
+/***********************************************************************************/
+/* This is the revert majick */
+
+static GList *
+get_packages_with_mod_flag (GList *packages,
+ PackageModification mod)
+{
+ GList *it;
+ GList *res;
+
+ res = NULL;
+ for (it = packages; it; it = g_list_next (it)) {
+ PackageData *pack;
+ pack = (PackageData*)it->data;
+ if (pack->modify_status == mod) {
+ res = g_list_prepend (res, pack);
+ }
+ if (pack->soft_depends) {
+ res = g_list_concat (res,
+ get_packages_with_mod_flag (pack->soft_depends, mod));
+ }
+ if (pack->modifies) {
+ res = g_list_concat (res,
+ get_packages_with_mod_flag (pack->modifies, mod));
+ }
+ }
+ return res;
+}
+
+/* Function to prune the uninstall list for elements marked as downgrade */
static void
-set_toplevel (PackageData *package,
- EazelInstall *service)
+check_uninst_vs_downgrade (GList **inst,
+ GList **down)
{
- package->toplevel = TRUE;
+ GList *it;
+ GList *remove;
+
+ remove = NULL;
+ for (it = *inst; it; it = g_list_next (it)) {
+ GList *entry;
+ PackageData *pack;
+
+ pack = (PackageData*)it->data;
+ entry = g_list_find_custom (*down, pack->name, (GCompareFunc)eazel_install_package_name_compare);
+ if (entry != NULL) {
+ remove = g_list_prepend (remove, it->data);
+ }
+ }
+
+ for (it = remove; it; it = g_list_next (it)) {
+ (*inst) = g_list_remove (*inst, it->data);
+ }
+}
+
+static void
+debug_revert (PackageData *pack, char *str)
+{
+ char *name = packagedata_get_readable_name (pack);
+ g_message ("will %s %s", str, name);
+ g_free (name);
+}
+
+/***********************************************************************************/
+/* This is the uninstall dep check majick */
+
+static int
+compare_break_to_package_by_name (PackageBreaks *breakage, PackageData *pack)
+{
+ PackageData *broken_package = packagebreaks_get_package (breakage);
+
+ return eazel_install_package_compare (broken_package, pack);
}
+/* This traverses upwards in the deptree from the initial list, and adds
+ all packages that will break to "breaks" */
+static void
+eazel_uninstall_upward_traverse (EazelInstall *service,
+ GList **packages,
+ GList **failed,
+ GList **breaks)
+{
+ GList *iterator;
+ /*
+ Create set
+ add all packs from packages to set
+ dep check
+ for all break, add to packages and recurse
+ */
+
+ trilobite_debug ("in eazel_uninstall_upward_traverse");
+
+ g_assert (packages!=NULL);
+ g_assert (*packages!=NULL);
+ g_assert (breaks!=NULL);
+ g_assert (*breaks==NULL);
+
+ /* Open the package system */
+
+ /* Add all packages to the set */
+
+ for (iterator = *packages; iterator; iterator = g_list_next (iterator)) {
+ PackageData *pack = (PackageData*)iterator->data;
+ GList *matches = NULL;
+ GList *match_iterator;
+ GList *tmp_breaks = NULL;
+ GList *b_iterator = NULL;
+
+ /* Get the packages required by pack */
+ trilobite_debug ("checking reqs by %p %s", pack, rpmname_from_packagedata (pack));
+ matches = eazel_package_system_query (service->private->package_system,
+ service->private->cur_root,
+ pack,
+ EAZEL_PACKAGE_SYSTEM_QUERY_REQUIRES,
+ PACKAGE_FILL_NO_DIRS_IN_PROVIDES | PACKAGE_FILL_NO_DEPENDENCIES);
+
+ /* For all of them, mark as a break conflict */
+ for (match_iterator = matches; match_iterator; match_iterator = g_list_next (match_iterator)) {
+ PackageData *requiredby = (PackageData*)match_iterator->data;;
+
+ requiredby->status = PACKAGE_DEPENDENCY_FAIL;
+ pack->status = PACKAGE_BREAKS_DEPENDENCY;
+ trilobite_debug ("logic.c: %p %s requires %p %s",
+ requiredby, requiredby->name,
+ pack, pack->name);
+
+ /* If the broken package is in packages, just continue */
+ if (g_list_find_custom (*packages, requiredby,
+ (GCompareFunc)eazel_install_package_compare)) {
+ trilobite_debug ("skip %p %s", requiredby, requiredby->name);
+ continue;
+ }
+
+ /* only add to breaks if it's a new breakage */
+ if (g_list_find_custom (*breaks, (gpointer)requiredby,
+ (GCompareFunc)compare_break_to_package_by_name)) {
+ (*breaks) = g_list_prepend ((*breaks), requiredby);
+ }
+
+ /* Create a FeatureMissing breakage */
+ {
+ PackageFeatureMissing *breakage = packagefeaturemissing_new ();
+ packagebreaks_set_package (PACKAGEBREAKS (breakage), requiredby);
+ packagedata_add_to_breaks (pack, PACKAGEBREAKS (breakage));
+ gtk_object_unref (GTK_OBJECT (breakage));
+ }
+
+ /* If the pac has not been failed yet (and is a toplevel),
+ fail it */
+ if (!g_list_find_custom (*failed, (gpointer)pack->name,
+ (GCompareFunc)eazel_install_package_name_compare) &&
+ pack->toplevel) {
+ (*failed) = g_list_prepend (*failed, pack);
+ }
+ }
+ g_list_foreach (matches, (GFunc)gtk_object_unref, NULL);
+ g_list_free (matches);
+
+ /* Now check the packages that broke, this is where eg. uninstalling
+ glib begins to take forever */
+ if (*breaks) {
+ eazel_uninstall_upward_traverse (service, breaks, failed, &tmp_breaks);
+ }
+
+ /* Add the result from the recursion */
+ for (b_iterator = tmp_breaks; b_iterator; b_iterator = g_list_next (b_iterator)) {
+ (*breaks) = g_list_prepend ((*breaks), b_iterator->data);
+ }
+ }
+
+ /* Remove the failed packages */
+ for (iterator = *failed; iterator; iterator = g_list_next (iterator)) {
+ (*packages) = g_list_remove (*packages, iterator->data);
+ }
+
+ trilobite_debug ("out eazel_uninstall_upward_traverse");
+}
+
+static void
+eazel_uninstall_check_for_install (EazelInstall *service,
+ GList **packages,
+ GList **failed)
+{
+ GList *iterator;
+ GList *remove = NULL;
+ GList *result = NULL;
+
+ trilobite_debug ("in eazel_uninstall_check_for_install");
+ g_assert (packages);
+ trilobite_debug ("g_list_length (*packages) = %d", g_list_length (*packages));
+ for (iterator = *packages; iterator; iterator = g_list_next (iterator)) {
+ PackageData *pack = (PackageData*)iterator->data;
+
+ if (eazel_package_system_is_installed (service->private->package_system,
+ service->private->cur_root,
+ pack->name,
+ pack->version,
+ pack->minor,
+ EAZEL_SOFTCAT_SENSE_EQ)) {
+
+ pack->toplevel = TRUE;
+ result = g_list_prepend (result, pack);
+ } else {
+ pack->status = PACKAGE_CANNOT_OPEN;
+ remove = g_list_prepend (remove, pack);
+ }
+ }
+
+ for (iterator = remove; iterator; iterator=g_list_next (iterator)) {
+ (*packages) = g_list_remove (*packages, iterator->data);
+ (*failed) = g_list_prepend (*failed, iterator->data);
+ }
+ g_list_free (remove);
+ remove = NULL;
+
+ trilobite_debug ("g_list_length (*packages) = %d", g_list_length (*packages));
+ trilobite_debug ("g_list_length (result) = %d", g_list_length (result));
+
+ g_list_free (*packages);
+ (*packages) = result;
+
+ trilobite_debug ("out eazel_uninstall_check_for_install");
+}
+
+/* Calls the upward and downward traversal */
+static void
+eazel_uninstall_globber (EazelInstall *service,
+ GList **packages,
+ GList **failed)
+{
+ GList *iterator;
+ GList *tmp;
+
+ /*
+ call upward with packages
+ call downward with packages and &tmp
+ add all from &tmp to packages
+ */
+
+ trilobite_debug ("in eazel_uninstall_globber");
+
+ tmp = NULL;
+
+ eazel_uninstall_check_for_install (service, packages, failed);
+ for (iterator = *failed; iterator; iterator = g_list_next (iterator)) {
+ trilobite_debug ("not installed %p %s",
+ (PackageData*)iterator->data, ((PackageData*)iterator->data)->name);
+ eazel_install_emit_uninstall_failed (service, (PackageData*)iterator->data);
+ }
+ g_list_foreach (*failed, (GFunc)gtk_object_unref, NULL);
+ g_list_free (*failed);
+
+ /* If there are still packages and we're not forcing,
+ do upwards traversel */
+ if (*packages && !eazel_install_get_force (service)) {
+ eazel_uninstall_upward_traverse (service, packages, failed, &tmp);
+
+#if EI2_DEBUG & 0x4
+ if (*failed) {
+ trilobite_debug ("FAILED");
+ dump_tree (*failed);
+ }
+#endif
+ for (iterator = *failed; iterator; iterator = g_list_next (iterator)) {
+ PackageData *pack = (PackageData*)iterator->data;
+ trilobite_debug ("failed %p %s", pack, pack->name);
+ //dump_one_package (GTK_OBJECT (pack), "");
+ eazel_install_emit_uninstall_failed (service, pack);
+ }
+ g_list_foreach (*failed, (GFunc)gtk_object_unref, NULL);
+ g_list_free (*failed);
+ g_list_free (tmp);
+ }
+
+ trilobite_debug ("out eazel_uninstall_glob");
+}
+
+
+/***********************************************************************************/
+
+/* These are the methods exposed to the the rest of the service object */
+
EazelInstallOperationStatus
install_packages (EazelInstall *service, GList *categories)
{
@@ -1726,7 +2043,7 @@ install_packages (EazelInstall *service, GList *categories)
#endif
if (packages) {
if (eazel_install_emit_preflight_check (service, packages)) {
- int flags = EAZEL_PACKAGE_SYSTEM_OPERATION_UPGRADE | EAZEL_PACKAGE_SYSTEM_OPERATION_FORCE;
+ int flags = EAZEL_PACKAGE_SYSTEM_OPERATION_UPGRADE | EAZEL_PACKAGE_SYSTEM_OPERATION_DOWNGRADE | EAZEL_PACKAGE_SYSTEM_OPERATION_FORCE;
gboolean go_ahead = TRUE;
/* FIXME: bugzilla.eazel.com 5722
@@ -1739,10 +2056,10 @@ install_packages (EazelInstall *service, GList *categories)
}
}
if (go_ahead) {
- execute (service, packages, EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL, flags);
- /* FIXME: bugzilla.eazel.com 5723
- we need to detect if install_failed_signal was called */
- result = EAZEL_INSTALL_INSTALL_OK;
+ /* Execute the operation */
+ if (execute (service, packages, EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL, flags)) {
+ result = EAZEL_INSTALL_INSTALL_OK;
+ }
}
}
}
@@ -1761,13 +2078,98 @@ install_packages (EazelInstall *service, GList *categories)
EazelInstallOperationStatus
uninstall_packages (EazelInstall *service, GList *categories)
{
- EazelInstallOperationStatus result = EAZEL_INSTALL_NOTHING;
+ EazelInstallStatus result = EAZEL_INSTALL_NOTHING;
+ GList *packages = NULL;
+ GList *failed = NULL;
+
+ trilobite_debug (" --> uninstall_all_packages");
+ packages = packagedata_list_copy (categorylist_flatten_to_packagelist (categories), TRUE);
+ eazel_uninstall_globber (service, &packages, &failed);
+
+ if (packages) {
+ if (eazel_install_emit_preflight_check (service, packages)) {
+ int flags = EAZEL_PACKAGE_SYSTEM_OPERATION_FORCE;
+ if (execute (service, packages, EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL, flags)) {
+ result = EAZEL_INSTALL_UNINSTALL_OK;
+ }
+ }
+ }
+
+ g_list_foreach (packages, (GFunc)gtk_object_unref, NULL);
+ g_list_free (packages);
+
+ trilobite_debug ("uninstall returns returning %s",
+ result == EAZEL_INSTALL_UNINSTALL_OK ? "OK" : "FAILED");
+ trilobite_debug (" <-- uninstall_all_packages");
return result;
}
-EazelInstallOperationStatus
-revert_transaction (EazelInstall *service, GList *packages)
+EazelInstallStatus
+revert_transaction (EazelInstall *service,
+ GList *packages)
{
- EazelInstallOperationStatus result = EAZEL_INSTALL_NOTHING;
+ GList *uninst, *inst, *upgrade, *downgrade;
+ CategoryData *cat;
+ GList *categories;
+ EazelInstallStatus result = EAZEL_INSTALL_NOTHING;
+
+ uninst = get_packages_with_mod_flag (packages, PACKAGE_MOD_INSTALLED);
+ inst = get_packages_with_mod_flag (packages, PACKAGE_MOD_UNINSTALLED);
+ upgrade = get_packages_with_mod_flag (packages, PACKAGE_MOD_DOWNGRADED);
+ downgrade = get_packages_with_mod_flag (packages, PACKAGE_MOD_UPGRADED);
+
+ check_uninst_vs_downgrade (&uninst, &downgrade);
+
+ g_list_foreach (uninst, (GFunc)debug_revert, "uninstall");
+ g_list_foreach (inst, (GFunc)debug_revert, "install");
+ g_list_foreach (downgrade, (GFunc)debug_revert, "downgrade");
+ g_list_foreach (upgrade, (GFunc)debug_revert, "upgrade");
+
+ cat = categorydata_new ();
+ categories = g_list_prepend (NULL, cat);
+
+ if (uninst) {
+ eazel_install_set_uninstall (service, TRUE);
+ eazel_install_set_downgrade (service, FALSE);
+ eazel_install_set_update (service, FALSE);
+ cat->packages = uninst;
+ if (uninstall_packages (service, categories) == EAZEL_INSTALL_UNINSTALL_OK) {
+ result = EAZEL_INSTALL_REVERSION_OK;
+ }
+ }
+ if (inst) {
+ eazel_install_set_uninstall (service, FALSE);
+ eazel_install_set_downgrade (service, FALSE);
+ eazel_install_set_update (service, FALSE);
+ cat->packages = inst;
+ if (install_packages (service, categories) == EAZEL_INSTALL_UNINSTALL_OK) {
+ result = EAZEL_INSTALL_REVERSION_OK;
+ }
+ }
+ if (downgrade) {
+ eazel_install_set_uninstall (service, FALSE);
+ eazel_install_set_downgrade (service, TRUE);
+ eazel_install_set_update (service, FALSE);
+ cat->packages = downgrade;
+ if (install_packages (service, categories) == EAZEL_INSTALL_UNINSTALL_OK) {
+ result = EAZEL_INSTALL_REVERSION_OK;
+ }
+ }
+ if (upgrade) {
+ eazel_install_set_uninstall (service, FALSE);
+ eazel_install_set_downgrade (service, TRUE);
+ eazel_install_set_update (service, TRUE);
+ cat->packages = upgrade;
+ if (install_packages (service, categories) == EAZEL_INSTALL_UNINSTALL_OK) {
+ result = EAZEL_INSTALL_REVERSION_OK;
+ }
+ }
+
+
+ categorydata_destroy (cat);
+ g_list_free (categories);
+
return result;
}
+
+
diff --git a/components/services/install/lib/eazel-install-object.c b/components/services/install/lib/eazel-install-object.c
index c914de236..f5d874bd4 100644
--- a/components/services/install/lib/eazel-install-object.c
+++ b/components/services/install/lib/eazel-install-object.c
@@ -64,6 +64,7 @@ enum {
DOWNLOAD_PROGRESS,
PREFLIGHT_CHECK,
INSTALL_PROGRESS,
+ UNINSTALL_PROGRESS,
DOWNLOAD_FAILED,
MD5_CHECK_FAILED,
INSTALL_FAILED,
@@ -123,6 +124,9 @@ void eazel_install_emit_feature_consistency_check_default (EazelInstall *service
void eazel_install_emit_install_progress_default (EazelInstall *service,
const PackageData *pack,
int, int, int, int, int, int);
+void eazel_install_emit_uninstall_progress_default (EazelInstall *service,
+ const PackageData *pack,
+ int, int, int, int, int, int);
void eazel_install_emit_download_progress_default (EazelInstall *service,
const PackageData *package,
int amount,
@@ -200,6 +204,7 @@ eazel_install_finalize (GtkObject *object)
g_list_free (service->private->root_dirs);
g_list_free (service->private->transaction);
+ g_list_free (service->private->failed_packages);
g_free (service->private->transaction_dir);
g_free (service->private->cur_root);
@@ -235,13 +240,19 @@ eazel_install_start_signal (EazelPackageSystem *system,
service->private->infoblock[2]++;
switch (op) {
case EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL:
- case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
eazel_install_emit_install_progress (service,
pack,
service->private->infoblock[2], service->private->infoblock[3],
0, pack->bytesize,
service->private->infoblock[4], service->private->infoblock[5]);
break;
+ case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
+ eazel_install_emit_uninstall_progress (service,
+ pack,
+ service->private->infoblock[2], service->private->infoblock[3],
+ 0, pack->bytesize,
+ service->private->infoblock[4], service->private->infoblock[5]);
+ break;
default:
break;
}
@@ -256,16 +267,29 @@ eazel_install_end_signal (EazelPackageSystem *system,
{
switch (op) {
case EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL:
- case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
eazel_install_emit_install_progress (service,
pack,
service->private->infoblock[2], service->private->infoblock[3],
pack->bytesize, pack->bytesize,
service->private->infoblock[4], service->private->infoblock[5]);
break;
+ case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
+ eazel_install_emit_uninstall_progress (service,
+ pack,
+ service->private->infoblock[2], service->private->infoblock[3],
+ pack->bytesize, pack->bytesize,
+ service->private->infoblock[4], service->private->infoblock[5]);
+ break;
default:
break;
}
+ if (pack->toplevel) {
+ if (g_list_find (service->private->failed_packages, (PackageData*)pack) == NULL) {
+ g_message ("Adding %s to transaction", pack->name);
+ service->private->transaction = g_list_prepend (service->private->transaction,
+ (PackageData*)pack);
+ }
+ }
return TRUE;
}
@@ -280,13 +304,19 @@ eazel_install_progress_signal (EazelPackageSystem *system,
if ((info[0] != 0) && (info[0] != info[1])) {
switch (op) {
case EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL:
- case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
eazel_install_emit_install_progress (service,
pack,
service->private->infoblock[2], service->private->infoblock[3],
info[0], pack->bytesize,
info[4], info[5]);
break;
+ case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
+ eazel_install_emit_uninstall_progress (service,
+ pack,
+ service->private->infoblock[2], service->private->infoblock[3],
+ info[0], pack->bytesize,
+ info[4], info[5]);
+ break;
default:
break;
}
@@ -301,6 +331,10 @@ eazel_install_failed_signal (EazelPackageSystem *system,
EazelInstall *service)
{
trilobite_debug ("*** %s failed", pack->name);
+
+ service->private->failed_packages = g_list_prepend (service->private->failed_packages,
+ (PackageData*)pack);
+
if (pack->toplevel) {
trilobite_debug ("emiting failed for %s", pack->name);
if (op==EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL) {
@@ -461,6 +495,15 @@ eazel_install_class_initialize (EazelInstallClass *klass)
GTK_TYPE_NONE, 7, GTK_TYPE_POINTER,
GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,
GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT);
+ signals[UNINSTALL_PROGRESS] =
+ gtk_signal_new ("uninstall_progress",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EazelInstallClass, uninstall_progress),
+ eazel_install_gtk_marshal_NONE__POINTER_INT_INT_INT_INT_INT_INT,
+ GTK_TYPE_NONE, 7, GTK_TYPE_POINTER,
+ GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT,
+ GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT);
signals[DOWNLOAD_FAILED] =
gtk_signal_new ("download_failed",
GTK_RUN_LAST,
@@ -510,6 +553,7 @@ eazel_install_class_initialize (EazelInstallClass *klass)
klass->file_uniqueness_check = NULL;
klass->feature_consistency_check = NULL;
klass->install_progress = NULL;
+ klass->uninstall_progress = NULL;
klass->download_progress = NULL;
klass->download_failed = NULL;
klass->md5_check_failed = NULL;
@@ -522,6 +566,7 @@ eazel_install_class_initialize (EazelInstallClass *klass)
klass->file_uniqueness_check = eazel_install_emit_file_uniqueness_check_default;
klass->feature_consistency_check = eazel_install_emit_feature_consistency_check_default;
klass->install_progress = eazel_install_emit_install_progress_default;
+ klass->uninstall_progress = eazel_install_emit_uninstall_progress_default;
klass->download_progress = eazel_install_emit_download_progress_default;
klass->download_failed = eazel_install_emit_download_failed_default;
klass->md5_check_failed = eazel_install_emit_md5_check_failed_default;
@@ -666,6 +711,7 @@ eazel_install_initialize (EazelInstall *service) {
(GCompareFunc)g_str_equal);
service->private->downloaded_files = NULL;
service->private->transaction = NULL;
+ service->private->failed_packages = NULL;
service->private->revert = FALSE;
service->private->ssl_rename = FALSE;
service->private->ignore_file_conflicts = FALSE;
@@ -687,7 +733,7 @@ eazel_install_initialize (EazelInstall *service) {
char *tmp = NULL;
#ifndef EAZEL_INSTALL_SLIM
- tmp = g_strdup_printf ("%s/.nautilus/rpmdb/", g_get_home_dir ());
+ tmp = g_strdup_printf ("%s/.nautilus/packagedb/", g_get_home_dir ());
list = g_list_prepend (list, g_strdup (g_get_home_dir ()));
list = g_list_prepend (list, tmp);
#else
@@ -1158,7 +1204,6 @@ eazel_install_install_packages (EazelInstall *service,
g_warning (_("Install failed"));
}
- eazel_install_unlock_tmp_dir (service);
trilobite_debug ("service->private->downloaded_files = 0x%p",
(unsigned int)service->private->downloaded_files);
@@ -1199,15 +1244,7 @@ eazel_install_uninstall_packages (EazelInstall *service, GList *categories, cons
eazel_install_fetch_remote_package_list (service);
}
-/*
- FIXME: bugzilla.eazel.com 5752
- if (eazel_install_get_ei2 (service)) {
- result = uninstall_packages (service, categories);
- } else {
- result = ei_uninstall_packages (service, categories);
- }
-*/
- result = ei_uninstall_packages (service, categories);
+ result = uninstall_packages (service, categories);
if (result == EAZEL_INSTALL_NOTHING) {
g_warning (_("Uninstall failed"));
@@ -1232,17 +1269,7 @@ eazel_install_revert_transaction_from_xmlstring (EazelInstall *service,
service->private->revert = TRUE;
if (create_temporary_directory (service)) {
-
-/*
- FIXME: bugzilla.eazel.com 5753
- if (eazel_install_get_ei2 (service)) {
- result = revert_transaction (service, packages);
- } else {
- result = ei_revert_transaction (service, packages);
- }
-*/
- result = ei_revert_transaction (service, packages);
- eazel_install_unlock_tmp_dir (service);
+ result = revert_transaction (service, packages);
} else {
result = EAZEL_INSTALL_NOTHING;
}
@@ -1293,6 +1320,110 @@ eazel_install_add_repository (EazelInstall *service, const char *dir)
service->private->local_repositories = g_list_prepend (service->private->local_repositories, g_strdup (dir));
}
+static void
+eazel_install_do_transaction_save_report_helper (xmlNodePtr node,
+ GList *packages)
+{
+ GList *iterator;
+
+ for (iterator = packages; iterator; iterator = g_list_next (iterator)) {
+ PackageData *pack;
+ char *tmp;
+ pack = (PackageData*)iterator->data;
+ switch (pack->modify_status) {
+ case PACKAGE_MOD_INSTALLED:
+ tmp = g_strdup_printf ("Installed %s", pack->name);
+ xmlNewChild (node, NULL, "DESCRIPTION", tmp);
+ g_free (tmp);
+ break;
+ case PACKAGE_MOD_UNINSTALLED:
+ tmp = g_strdup_printf ("Uninstalled %s", pack->name);
+ xmlNewChild (node, NULL, "DESCRIPTION", tmp);
+ g_free (tmp);
+ break;
+ default:
+ break;
+ }
+ if (pack->modifies) {
+ eazel_install_do_transaction_save_report_helper (node, pack->modifies);
+ }
+ }
+}
+
+void
+eazel_install_save_transaction_report (EazelInstall *service)
+{
+ FILE *outfile;
+ xmlDocPtr doc;
+ xmlNodePtr node, root;
+ char *name = NULL;
+
+ if (eazel_install_get_transaction_dir (service) == NULL) {
+ g_warning ("Transaction directory not set, not storing transaction report");
+ }
+
+ /* Ensure the transaction dir is present */
+ if (! g_file_test (eazel_install_get_transaction_dir (service), G_FILE_TEST_ISDIR)) {
+ int retval;
+ retval = mkdir (eazel_install_get_transaction_dir (service), 0755);
+ if (retval < 0) {
+ if (errno != EEXIST) {
+ g_warning (_("Could not create transaction directory (%s)! ***\n"),
+ eazel_install_get_transaction_dir (service));
+ return;
+ }
+ }
+ }
+
+ /* Create xml */
+ doc = xmlNewDoc ("1.0");
+ root = node = xmlNewNode (NULL, "TRANSACTION");
+ xmlDocSetRootElement (doc, node);
+
+ /* Make a unique name */
+ name = g_strdup_printf ("%s/transaction.%lu", eazel_install_get_transaction_dir (service),
+ (unsigned long) time (NULL));
+ while (g_file_test (name, G_FILE_TEST_ISFILE)) {
+ g_free (name);
+ sleep (1);
+ name = g_strdup_printf ("%s/transaction.%lu",
+ eazel_install_get_transaction_dir (service),
+ (unsigned long) time (NULL));
+ }
+
+ trilobite_debug (_("Writing transaction to %s"), name);
+
+ /* Open and save */
+ outfile = fopen (name, "w");
+ xmlAddChild (root, eazel_install_packagelist_to_xml (service->private->transaction, FALSE));
+ node = xmlAddChild (node, xmlNewNode (NULL, "DESCRIPTIONS"));
+
+ {
+ char *tmp;
+ tmp = g_strdup_printf ("%lu", (unsigned long) time (NULL));
+ xmlNewChild (node, NULL, "DATE", tmp);
+ g_free (tmp);
+ }
+
+ eazel_install_do_transaction_save_report_helper (node, service->private->transaction);
+
+ xmlDocDump (outfile, doc);
+
+ fclose (outfile);
+ g_free (name);
+}
+
+void
+eazel_install_init_transaction (EazelInstall *service)
+{
+ /* Null the list of files met in the transaction */
+ g_list_free (service->private->transaction);
+ service->private->transaction = NULL;
+
+ /* Null the list of files met in the transaction */
+ g_list_free (service->private->transaction);
+ service->private->transaction = NULL;
+}
/************************************************
Signal emitters and default handlers.
@@ -1428,13 +1559,56 @@ eazel_install_emit_install_progress_default (EazelInstall *service,
}
void
+eazel_install_emit_uninstall_progress (EazelInstall *service,
+ const PackageData *pack,
+ int package_num, int num_packages,
+ int package_size_completed, int package_size_total,
+ int total_size_completed, int total_size)
+{
+ EAZEL_INSTALL_SANITY(service);
+ gtk_signal_emit (GTK_OBJECT (service), signals[UNINSTALL_PROGRESS],
+ pack,
+ package_num, num_packages,
+ package_size_completed, package_size_total,
+ total_size_completed, total_size);
+
+}
+
+void
+eazel_install_emit_uninstall_progress_default (EazelInstall *service,
+ const PackageData *pack,
+ int package_num, int num_packages,
+ int package_size_completed, int package_size_total,
+ int total_size_completed, int total_size)
+{
+#ifndef EAZEL_INSTALL_NO_CORBA
+ CORBA_Environment ev;
+ CORBA_exception_init (&ev);
+ EAZEL_INSTALL_SANITY(service);
+
+ if (service->callback != CORBA_OBJECT_NIL) {
+ GNOME_Trilobite_Eazel_PackageDataStruct *package;
+ package = corba_packagedatastruct_from_packagedata (pack);
+ GNOME_Trilobite_Eazel_InstallCallback_uninstall_progress (service->callback,
+ package,
+ package_num, num_packages,
+ package_size_completed, package_size_total,
+ total_size_completed, total_size,
+ &ev);
+ CORBA_free (package);
+ }
+ CORBA_exception_free (&ev);
+#endif /* EAZEL_INSTALL_NO_CORBA */
+}
+
+void
eazel_install_emit_download_progress (EazelInstall *service,
const PackageData *pack,
int amount,
int total)
{
EAZEL_INSTALL_SANITY(service);
- gtk_signal_emit (GTK_OBJECT (service), signals[DOWNLOAD_PROGRESS], pack, amount, total);
+ //gtk_signal_emit (GTK_OBJECT (service), signals[DOWNLOAD_PROGRESS], pack, amount, total);
}
void
diff --git a/components/services/install/lib/eazel-install-private.h b/components/services/install/lib/eazel-install-private.h
index 087242717..f2900eea7 100644
--- a/components/services/install/lib/eazel-install-private.h
+++ b/components/services/install/lib/eazel-install-private.h
@@ -74,12 +74,12 @@ struct _EazelInstallPrivate {
but not erased. */
GHashTable *name_to_package_hash;
- /* This holds the toplevel packages requested for
- install/upgrade/uninstall.
- Entries are added in eazel-install-rpm-glue.c, as
- stuff is done.
- It's cleaned up in the end of eazel_install_start_transaction */
+ /* During an operation, this logs the toplevel packages
+ that were installed */
GList *transaction;
+
+ /* During an operation, this logs all packages that failed */
+ GList *failed_packages;
/* The logfile used for the object */
FILE *logfile;
diff --git a/components/services/install/lib/eazel-install-problem.c b/components/services/install/lib/eazel-install-problem.c
index 59588e54b..21fac31cf 100644
--- a/components/services/install/lib/eazel-install-problem.c
+++ b/components/services/install/lib/eazel-install-problem.c
@@ -101,7 +101,7 @@ get_detailed_messages_breaks_foreach (PackageBreaks *breakage, GetErrorsForEachD
}
static void
-get_detailed_messages_foreach (PackageData *pack, GetErrorsForEachData *data)
+get_detailed_messages_foreach (GtkObject *foo, GetErrorsForEachData *data)
{
char *message = NULL;
char *required = NULL;
@@ -110,6 +110,17 @@ get_detailed_messages_foreach (PackageData *pack, GetErrorsForEachData *data)
GList **errors = &(data->errors);
PackageData *previous_pack = NULL;
PackageData *top_pack = NULL;
+ PackageData *pack = NULL;
+
+ if (IS_PACKAGEDATA (foo)) {
+ pack = PACKAGEDATA (foo);
+ } else if (IS_PACKAGEBREAKS (foo)) {
+ pack = packagebreaks_get_package (PACKAGEBREAKS (foo));
+ } else if (IS_PACKAGEDEPENDENCY (foo)) {
+ pack = PACKAGEDEPENDENCY (foo)->package;
+ } else {
+ g_assert_not_reached ();
+ }
if (data->path) {
previous_pack = (PackageData*)(data->path->data);
@@ -124,6 +135,7 @@ get_detailed_messages_foreach (PackageData *pack, GetErrorsForEachData *data)
switch (pack->status) {
case PACKAGE_UNKNOWN_STATUS:
+ case PACKAGE_CANCELLED:
break;
case PACKAGE_SOURCE_NOT_SUPPORTED:
message = g_strdup_printf (_("%s is a source package, which is not yet supported"),
@@ -141,7 +153,7 @@ get_detailed_messages_foreach (PackageData *pack, GetErrorsForEachData *data)
}
break;
case PACKAGE_DEPENDENCY_FAIL:
- if (pack->soft_depends) {
+ if (pack->depends) {
} else {
if (previous_pack && previous_pack->status == PACKAGE_BREAKS_DEPENDENCY) {
@@ -231,7 +243,7 @@ get_detailed_messages_foreach (PackageData *pack, GetErrorsForEachData *data)
/* Create the path list */
data->path = g_list_prepend (data->path, pack);
- g_list_foreach (pack->soft_depends, (GFunc)get_detailed_messages_foreach, data);
+ g_list_foreach (pack->depends, (GFunc)get_detailed_messages_foreach, data);
g_list_foreach (pack->modifies, (GFunc)get_detailed_messages_foreach, data);
g_list_foreach (pack->breaks, (GFunc)get_detailed_messages_breaks_foreach, data);
@@ -240,7 +252,7 @@ get_detailed_messages_foreach (PackageData *pack, GetErrorsForEachData *data)
}
static void
-get_detailed_uninstall_messages_foreach (PackageData *pack,
+get_detailed_uninstall_messages_foreach (GtkObject *foo,
GetErrorsForEachData *data)
{
char *message = NULL;
@@ -250,6 +262,17 @@ get_detailed_uninstall_messages_foreach (PackageData *pack,
GList **errors = &(data->errors);
PackageData *previous_pack = NULL;
PackageData *top_pack = NULL;
+ PackageData *pack = NULL;
+
+ if (IS_PACKAGEDATA (foo)) {
+ pack = PACKAGEDATA (foo);
+ } else if (IS_PACKAGEBREAKS (foo)) {
+ pack = packagebreaks_get_package (PACKAGEBREAKS (foo));
+ } else if (IS_PACKAGEDEPENDENCY (foo)) {
+ pack = PACKAGEDEPENDENCY (foo)->package;
+ } else {
+ g_assert_not_reached ();
+ }
if (data->path) {
previous_pack = (PackageData*)(data->path->data);
@@ -264,6 +287,7 @@ get_detailed_uninstall_messages_foreach (PackageData *pack,
switch (pack->status) {
case PACKAGE_UNKNOWN_STATUS:
+ case PACKAGE_CANCELLED:
break;
case PACKAGE_SOURCE_NOT_SUPPORTED:
message = g_strdup_printf (_("%s is a source package, which is not yet supported"),
@@ -310,7 +334,7 @@ get_detailed_uninstall_messages_foreach (PackageData *pack,
/* Create the path list */
data->path = g_list_prepend (data->path, pack);
- g_list_foreach (pack->soft_depends, (GFunc)get_detailed_uninstall_messages_foreach, data);
+ g_list_foreach (pack->depends, (GFunc)get_detailed_uninstall_messages_foreach, data);
g_list_foreach (pack->modifies, (GFunc)get_detailed_uninstall_messages_foreach, data);
g_list_foreach (pack->breaks, (GFunc)get_detailed_uninstall_messages_foreach, data);
@@ -613,10 +637,22 @@ get_detailed_cases_breaks_foreach (PackageBreaks *breakage, GetErrorsForEachData
- package status looks ok, check modification_status
*/
static void
-get_detailed_cases_foreach (PackageData *pack, GetErrorsForEachData *data)
+get_detailed_cases_foreach (GtkObject *foo,
+ GetErrorsForEachData *data)
{
/* GList **errors = &(data->errors); */
PackageData *previous_pack = NULL;
+ PackageData *pack = NULL;
+
+ if (IS_PACKAGEDATA (foo)) {
+ pack = PACKAGEDATA (foo);
+ } else if (IS_PACKAGEBREAKS (foo)) {
+ pack = packagebreaks_get_package (PACKAGEBREAKS (foo));
+ } else if (IS_PACKAGEDEPENDENCY (foo)) {
+ pack = PACKAGEDEPENDENCY (foo)->package;
+ } else {
+ g_assert_not_reached ();
+ }
#ifdef EIP_DEBUG
g_message ("get_detailed_cases_foreach (%p)", pack);
@@ -633,13 +669,14 @@ get_detailed_cases_foreach (PackageData *pack, GetErrorsForEachData *data)
switch (pack->status) {
case PACKAGE_UNKNOWN_STATUS:
+ case PACKAGE_CANCELLED:
break;
case PACKAGE_SOURCE_NOT_SUPPORTED:
break;
case PACKAGE_FILE_CONFLICT:
break;
case PACKAGE_DEPENDENCY_FAIL:
- if (pack->soft_depends) {
+ if (pack->depends) {
} else {
if (previous_pack && previous_pack->status == PACKAGE_BREAKS_DEPENDENCY) {
add_update_case (data->problem, pack, FALSE, &(data->errors));
@@ -672,7 +709,7 @@ get_detailed_cases_foreach (PackageData *pack, GetErrorsForEachData *data)
/* Create the path list */
data->path = g_list_prepend (data->path, pack);
- g_list_foreach (pack->soft_depends, (GFunc)get_detailed_cases_foreach, data);
+ g_list_foreach (pack->depends, (GFunc)get_detailed_cases_foreach, data);
g_list_foreach (pack->modifies, (GFunc)get_detailed_cases_foreach, data);
g_list_foreach (pack->breaks, (GFunc)get_detailed_cases_breaks_foreach, data);
@@ -686,9 +723,20 @@ get_detailed_cases_foreach (PackageData *pack, GetErrorsForEachData *data)
- package status looks ok, check modification_status
*/
static void
-get_detailed_uninstall_cases_foreach (PackageData *pack, GetErrorsForEachData *data)
+get_detailed_uninstall_cases_foreach (GtkObject *foo, GetErrorsForEachData *data)
{
PackageData *previous_pack = NULL;
+ PackageData *pack = NULL;
+
+ if (IS_PACKAGEDATA (foo)) {
+ pack = PACKAGEDATA (foo);
+ } else if (IS_PACKAGEBREAKS (foo)) {
+ pack = packagebreaks_get_package (PACKAGEBREAKS (foo));
+ } else if (IS_PACKAGEDEPENDENCY (foo)) {
+ pack = PACKAGEDEPENDENCY (foo)->package;
+ } else {
+ g_assert_not_reached ();
+ }
#ifdef EIP_DEBUG
g_message ("get_detailed_uninstall_cases_foreach (data->path = %p)", data->path);
@@ -706,6 +754,7 @@ get_detailed_uninstall_cases_foreach (PackageData *pack, GetErrorsForEachData *d
switch (pack->status) {
case PACKAGE_UNKNOWN_STATUS:
+ case PACKAGE_CANCELLED:
break;
case PACKAGE_SOURCE_NOT_SUPPORTED:
break;
@@ -733,7 +782,7 @@ get_detailed_uninstall_cases_foreach (PackageData *pack, GetErrorsForEachData *d
/* Create the path list */
data->path = g_list_prepend (data->path, pack);
- g_list_foreach (pack->soft_depends, (GFunc)get_detailed_uninstall_cases_foreach, data);
+ g_list_foreach (pack->depends, (GFunc)get_detailed_uninstall_cases_foreach, data);
g_list_foreach (pack->modifies, (GFunc)get_detailed_uninstall_cases_foreach, data);
g_list_foreach (pack->breaks, (GFunc)get_detailed_uninstall_cases_foreach, data);
@@ -744,7 +793,7 @@ get_detailed_uninstall_cases_foreach (PackageData *pack, GetErrorsForEachData *d
data->path = NULL;
}
- if (pack->toplevel) {
+ if (pack->toplevel && pack->status == PACKAGE_BREAKS_DEPENDENCY) {
/* This is just to make sure the toplevel is first */
data->packs = g_list_reverse (data->packs);
add_cascade_remove (data->problem, &(data->packs), FALSE, &(data->errors));
@@ -1105,9 +1154,9 @@ eazel_install_problem_tree_to_case (EazelInstallProblem *problem,
problem->in_step_problem_mode = FALSE;
if (uninstall) {
- get_detailed_uninstall_cases_foreach (pack_copy, &data);
+ get_detailed_uninstall_cases_foreach (GTK_OBJECT (pack_copy), &data);
} else {
- get_detailed_cases_foreach (pack_copy, &data);
+ get_detailed_cases_foreach (GTK_OBJECT (pack_copy), &data);
}
gtk_object_unref (GTK_OBJECT (pack_copy));
@@ -1133,9 +1182,9 @@ eazel_install_problem_tree_to_string (EazelInstallProblem *problem,
pack_copy = packagedata_copy (pack, TRUE);
if (uninstall) {
- get_detailed_uninstall_messages_foreach (pack_copy, &data);
+ get_detailed_uninstall_messages_foreach (GTK_OBJECT (pack_copy), &data);
} else {
- get_detailed_messages_foreach (pack_copy, &data);
+ get_detailed_messages_foreach (GTK_OBJECT (pack_copy), &data);
}
gtk_object_unref (GTK_OBJECT (pack_copy));
@@ -1267,7 +1316,6 @@ build_categories_from_problem_list (EazelInstallProblem *problem,
break;
case EI_PROBLEM_CASCADE_REMOVE: {
GList *iterator;
- g_message ("%s:%d cascade", __FILE__, __LINE__);
for (iterator = pcase->u.cascade.packages; iterator; iterator = g_list_next (iterator)) {
packages = g_list_prepend (packages, iterator->data);
}
diff --git a/components/services/install/lib/eazel-install-public.h b/components/services/install/lib/eazel-install-public.h
index 0e455d629..a23ea793a 100644
--- a/components/services/install/lib/eazel-install-public.h
+++ b/components/services/install/lib/eazel-install-public.h
@@ -49,10 +49,10 @@ extern "C" {
#define EAZEL_IS_INSTALL_CLASS(klass)(GTK_CHECK_CLASS_TYPE ((klass), TYPE_EAZEL_INSTALL))
typedef enum {
- EAZEL_INSTALL_NOTHING = 0,
- EAZEL_INSTALL_INSTALL_OK = 1<<0,
- EAZEL_INSTALL_UNINSTALL_OK = 1<<1,
- EAZEL_INSTALL_REVERSION_OK = 1<<2
+ EAZEL_INSTALL_NOTHING = 0x0,
+ EAZEL_INSTALL_INSTALL_OK = 0x1,
+ EAZEL_INSTALL_UNINSTALL_OK = 0x2,
+ EAZEL_INSTALL_REVERSION_OK = 0x4
} EazelInstallOperationStatus;
typedef enum {
@@ -88,6 +88,11 @@ struct _EazelInstallClass
int package_num, int num_packages,
int package_size_completed, int package_size_total,
int total_size_completed, int total_size);
+ void (*uninstall_progress) (EazelInstall *service,
+ const PackageData *pack,
+ int package_num, int num_packages,
+ int package_size_completed, int package_size_total,
+ int total_size_completed, int total_size);
void (*dependency_check) (EazelInstall *service, const PackageData *pack, const PackageData *needed);
/*
if the set URLType is PROTOCOL_HTTP, info is a HTTPError struc
@@ -159,6 +164,11 @@ void eazel_install_emit_install_progress (EazelInstall *service,
int package_num, int num_packages,
int package_size_completed, int package_size_total,
int total_size_completed, int total_size);
+void eazel_install_emit_uninstall_progress (EazelInstall *service,
+ const PackageData *pack,
+ int package_num, int num_packages,
+ int package_size_completed, int package_size_total,
+ int total_size_completed, int total_size);
void eazel_install_emit_download_progress (EazelInstall *service,
const PackageData *package,
int amount,
@@ -211,6 +221,8 @@ void eazel_install_revert_transaction_from_file (EazelInstall *service,
void eazel_install_delete_downloads (EazelInstall *service);
+void eazel_install_init_transaction (EazelInstall *service);
+void eazel_install_save_transaction_report (EazelInstall *service);
/******************************************************************************/
/* Beware, from hereonafter, it's #def madness, to make the get/set functions */
diff --git a/components/services/install/lib/eazel-package-system-rpm3.c b/components/services/install/lib/eazel-package-system-rpm3.c
index dd026473b..d6fd69bd7 100644
--- a/components/services/install/lib/eazel-package-system-rpm3.c
+++ b/components/services/install/lib/eazel-package-system-rpm3.c
@@ -123,7 +123,7 @@ rpmmonitorpiggybag_new (EazelPackageSystemRpm3 *system,
#ifdef USE_PERCENT
lc = localeconv ();
pig.separator = *(lc->decimal_point);
- trilobite_debug ("I am in in a %c country", pig.separator);
+ info (system, "I am in in a %c country", pig.separator);
pig.state = 1;
pig.bytes_read_in_line = 0;
pig.line[0] = '\0';
@@ -284,6 +284,25 @@ get_total_size_of_packages (const GList *packages)
return result;
}
+static void
+eazel_package_system_rpm3_set_mod_status (EazelPackageSystemRpm3 *system,
+ EazelPackageSystemOperation op,
+ PackageData *pack)
+{
+ if (pack->modify_status == PACKAGE_MOD_UNTOUCHED) {
+ switch (op) {
+ case EAZEL_PACKAGE_SYSTEM_OPERATION_INSTALL:
+ pack->modify_status = PACKAGE_MOD_INSTALLED;
+ break;
+ case EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL:
+ pack->modify_status = PACKAGE_MOD_UNINSTALLED;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
#ifdef USE_PERCENT
/* This monitors an rpm process pipe and emits
signals during execution */
@@ -414,6 +433,11 @@ monitor_rpm_process_pipe_percent_output (GIOChannel *source,
pig->bytes_installed += pig->pack->bytesize;
pig->packages_seen = g_list_prepend (pig->packages_seen,
pig->pack);
+
+ eazel_package_system_rpm3_set_mod_status (pig->system,
+ pig->op,
+ pig->pack);
+
eazel_package_system_emit_end (EAZEL_PACKAGE_SYSTEM (pig->system),
pig->op,
pig->pack);
@@ -863,16 +887,16 @@ eazel_package_system_rpm3_packagedata_fill_from_header (EazelPackageSystemRpm3 *
PackageData *package = packagedata_new ();
PackageDependency *pack_dep = packagedependency_new ();
- /* If it's a lib*.so* or a /yadayada, add to provides */
- if ((strncmp (requires_name[index], "lib", 3)==0 &&
- strstr (requires_name[index], ".so")) ||
+ /* If it's a lib*.so* or a /yadayada, but not ld-linux.so
+ or rpmlib( add to provides */
+ if (((strncmp (requires_name[index], "lib", 3)==0 && strstr (requires_name[index], ".so")) ||
(strncmp (requires_name[index], "ld-linux.so", 11) == 0) ||
- (*requires_name[index]=='/')) {
- /* Unless it has a ( in the name */
- if (strchr (requires_name[index], '(')==NULL) {
- package->features = g_list_prepend (package->features,
- g_strdup (requires_name[index]));
- }
+ (*requires_name[index]=='/')) &&
+ (strncmp (requires_name[index], "rpmlib(", 7) != 0)) {
+
+
+ package->features = g_list_prepend (package->features,
+ g_strdup (requires_name[index]));
} else {
/* Otherwise, add as a package name */
package->name = g_strdup (requires_name[index]);
@@ -881,7 +905,7 @@ eazel_package_system_rpm3_packagedata_fill_from_header (EazelPackageSystemRpm3 *
NULL : g_strdup (requires_version[index]);
}
/* If anything set, add dep */
- if (package->name || package->provides) {
+ if (package->name || package->features) {
pack_dep->sense = rpm_sense_to_softcat_sense (system,
requires_flag[index]);
package->archtype = trilobite_get_distribution_arch ();
@@ -1273,6 +1297,18 @@ monitor_subcommand_pipe (EazelPackageSystemRpm3 *system,
info (system, "ending monitor on %d", fd);
}
+static void
+eazel_package_system_rpm3_set_state (EazelPackageSystemRpm3 *system,
+ GList *packages,
+ PackageSystemStatus status) {
+ GList *iterator;
+ for (iterator = packages; iterator; iterator = g_list_next (iterator)) {
+ PackageData *pack = PACKAGEDATA (iterator->data);
+ pack->status = status;
+ }
+}
+
+
/* returns TRUE on success */
static gboolean
manual_rpm_command (GList *args, int *fd)
@@ -1352,6 +1388,7 @@ eazel_package_system_rpm3_execute (EazelPackageSystemRpm3 *system,
monitor_subcommand_pipe (system, fd, (GIOFunc)monitor_rpm_process_pipe, pig);
#endif
} else {
+ eazel_package_system_rpm3_set_state (system, pig->packages_to_expect, PACKAGE_CANCELLED);
/* FIXME: fail all the packages in pig */
}
}
@@ -1362,6 +1399,7 @@ static void
check_if_all_packages_seen (EazelPackageSystemRpm3 *system,
const char *dbpath,
EazelPackageSystemOperation op,
+ int flags,
GList *packages,
GList *seen)
{
@@ -1372,6 +1410,20 @@ check_if_all_packages_seen (EazelPackageSystemRpm3 *system,
for (iterator = packages; iterator; iterator = g_list_next (iterator)) {
PackageData *pack = (PackageData*)iterator->data;
+
+ if (flags & EAZEL_PACKAGE_SYSTEM_OPERATION_TEST) {
+ eazel_package_system_emit_start (EAZEL_PACKAGE_SYSTEM (system),
+ op,
+ pack);
+ eazel_package_system_rpm3_set_mod_status (system,
+ op,
+ pack);
+ eazel_package_system_emit_end (EAZEL_PACKAGE_SYSTEM (system),
+ op,
+ pack);
+ continue;
+ }
+
/* HACK: that fixes bugzilla.eazel.com 4914 */
if (op==EAZEL_PACKAGE_SYSTEM_OPERATION_UNINSTALL) {
if (eazel_package_system_is_installed (EAZEL_PACKAGE_SYSTEM (system),
@@ -1386,6 +1438,9 @@ check_if_all_packages_seen (EazelPackageSystemRpm3 *system,
eazel_package_system_emit_start (EAZEL_PACKAGE_SYSTEM (system),
op,
pack);
+ eazel_package_system_rpm3_set_mod_status (system,
+ op,
+ pack);
eazel_package_system_emit_end (EAZEL_PACKAGE_SYSTEM (system),
op,
pack);
@@ -1395,7 +1450,8 @@ check_if_all_packages_seen (EazelPackageSystemRpm3 *system,
pack,
(GCompareFunc)eazel_install_package_compare)) {
fail (system, "did not see %s", pack->name);
- eazel_package_system_emit_failed (EAZEL_PACKAGE_SYSTEM (system), op, pack);
+ eazel_package_system_emit_failed (EAZEL_PACKAGE_SYSTEM (system),
+ op, pack);
}
}
}
@@ -1427,7 +1483,7 @@ eazel_package_system_rpm3_install_uninstall (EazelPackageSystemRpm3 *system,
eazel_package_system_rpm3_execute (system, &pig, args);
destroy_string_list (args);
- check_if_all_packages_seen (system, dbpath, op, packages, pig.packages_seen);
+ check_if_all_packages_seen (system, dbpath, op, flags, packages, pig.packages_seen);
g_list_free (pig.packages_seen);
g_hash_table_foreach_remove (pig.name_to_package, (GHRFunc)clear_name_to_package, NULL);
diff --git a/components/services/install/lib/eazel-package-system-types.c b/components/services/install/lib/eazel-package-system-types.c
index 6c7d70d92..918e29d13 100644
--- a/components/services/install/lib/eazel-package-system-types.c
+++ b/components/services/install/lib/eazel-package-system-types.c
@@ -38,10 +38,11 @@
#include <libtrilobite/trilobite-core-utils.h>
-#define DEBUG_PACKAGE_ALLOCS
+#undef DEBUG_PACKAGE_ALLOCS
#ifdef DEBUG_PACKAGE_ALLOCS
static int report_all = 0;
+
static int package_total_allocs = 0, package_max = 0;
static int package_allocs = 0;
GList *packages_allocated = NULL;
@@ -106,7 +107,7 @@ categorydata_new (void)
result = g_new0 (CategoryData, 1);
#ifdef DEBUG_PACKAGE_ALLOCS
category_allocs ++;
- if (report_all) trilobite_debug ("category_allocs inced to %d (%p)", category_allocs, result);
+ if (report_all) trilobite_debug ("category_allocs increased to %d (%p)", category_allocs, result);
#endif /* DEBUG_PACKAGE_ALLOCS */
result->name = NULL;
result->description = NULL;
@@ -157,13 +158,13 @@ categorydata_destroy_foreach (CategoryData *cd, gpointer ununsed)
{
#ifdef DEBUG_PACKAGE_ALLOCS
category_allocs --;
- if (report_all) trilobite_debug ("category_allocs = %d (%p) %s", category_allocs, cd, cd ? cd->name: "?");
+ if (report_all) trilobite_debug ("category_allocs decreased to %d (%p) %s", category_allocs, cd, cd ? cd->name: "?");
#endif /* DEBUG_PACKAGE_ALLOCS */
g_return_if_fail (cd != NULL);
- if (g_list_length (cd->packages)) {
+ if (cd->packages) {
g_list_foreach (cd->packages, (GFunc)gtk_object_unref, NULL);
- }
+ } else trilobite_debug ("EMPTY");
g_list_free (cd->packages);
cd->packages = NULL;
if (g_list_length (cd->depends)) {
@@ -771,6 +772,9 @@ packagedata_status_enum_to_str (PackageSystemStatus st)
case PACKAGE_RESOLVED:
result = g_strdup ("RESOLVED");
break;
+ case PACKAGE_CANCELLED:
+ result = g_strdup ("CANCELLED");
+ break;
case PACKAGE_ALREADY_INSTALLED:
result = g_strdup ("ALREADY_INSTALLED");
break;
@@ -799,6 +803,7 @@ packagedata_status_str_to_enum (const char *st)
else if (strcmp (st, "CANNOT_OPEN")==0) { result = PACKAGE_CANNOT_OPEN; }
else if (strcmp (st, "PARTLY_RESOLVED")==0) { result = PACKAGE_PARTLY_RESOLVED; }
else if (strcmp (st, "RESOLVED")==0) { result = PACKAGE_RESOLVED; }
+ else if (strcmp (st, "CANCELLED")==0) { result = PACKAGE_CANCELLED; }
else if (strcmp (st, "ALREADY_INSTALLED")==0) { result = PACKAGE_ALREADY_INSTALLED; }
else if (strcmp (st, "CIRCULAR_DEPENDENCY")==0) { result = PACKAGE_CIRCULAR_DEPENDENCY; }
else { g_assert_not_reached (); result = PACKAGE_UNKNOWN_STATUS; };
diff --git a/components/services/install/lib/eazel-package-system-types.h b/components/services/install/lib/eazel-package-system-types.h
index 32c405802..680e79b1e 100644
--- a/components/services/install/lib/eazel-package-system-types.h
+++ b/components/services/install/lib/eazel-package-system-types.h
@@ -70,7 +70,8 @@ enum _PackageSystemStatus {
PACKAGE_PARTLY_RESOLVED,
PACKAGE_ALREADY_INSTALLED,
PACKAGE_CIRCULAR_DEPENDENCY,
- PACKAGE_RESOLVED
+ PACKAGE_RESOLVED,
+ PACKAGE_CANCELLED
};
/* Methods to convert enum to/from char* val. The returned
char* must not be freed */
@@ -109,6 +110,7 @@ enum _PackageFillFlags {
PACKAGE_FILL_NO_PROVIDES = 0x02,
PACKAGE_FILL_NO_DEPENDENCIES = 0x04,
PACKAGE_FILL_NO_DIRS_IN_PROVIDES = 0x8, /* only used if PACKAGE_FILL_NO_PROVIDES is not set */
+ PACAKGE_FILL_NO_FEATURES = 0x10,
PACKAGE_FILL_MINIMAL = 0x7fff,
PACKAGE_FILL_INVALID = 0x8000
};
diff --git a/components/services/install/lib/eazel-package-system.c b/components/services/install/lib/eazel-package-system.c
index 41b58e3e6..ffd77b432 100644
--- a/components/services/install/lib/eazel-package-system.c
+++ b/components/services/install/lib/eazel-package-system.c
@@ -263,7 +263,15 @@ eazel_package_system_install (EazelPackageSystem *system,
{
EPS_SANE (system);
g_assert (system->private->install);
- (*system->private->install) (system, root, packages, flags);
+
+ /* If we're in test mode, disable FORCE just to trigger
+ any potiental errors */
+ if (flags & EAZEL_PACKAGE_SYSTEM_OPERATION_TEST) {
+ (*system->private->install) (system, root, packages,
+ flags & ~EAZEL_PACKAGE_SYSTEM_OPERATION_FORCE);
+ } else {
+ (*system->private->install) (system, root, packages, flags);
+ }
}
void