summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEskil Heyn Olsen <eskil@eazel.com>2001-02-09 03:53:18 +0000
committerEskil Heyn Olsen <eskil@src.gnome.org>2001-02-09 03:53:18 +0000
commit28555b9819fec18b578409ebb429434a3a0ccced (patch)
tree09c211b8a2904eb6cf81cc573fc53c0ef670e7a5
parent19ec1fcb086d03e444e61683d82dac5c697edabe (diff)
downloadnautilus-28555b9819fec18b578409ebb429434a3a0ccced.tar.gz
reviewed by: Robey Pointer <robey@eazel.com>
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.
-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