diff -r a4f43ad0e0c8 -r 9df74ddb5638 plover-gtk/transactionhelper.c --- a/plover-gtk/transactionhelper.c Tue Jun 28 15:55:48 2016 +0100 +++ b/plover-gtk/transactionhelper.c Thu Mar 02 11:25:36 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 J. Ali Harlow + * Copyright (C) 2014, 2016 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include "config.h" #include +#include #include #include #include @@ -88,6 +89,7 @@ g_slist_foreach(helper->transactions,(GFunc)g_object_unref,NULL); g_slist_free(helper->transactions); helper->transactions=NULL; + g_clear_object(&helper->alternate_installed); g_clear_object(&helper->installed); g_clear_object(&helper->upstream); g_clear_object(&helper->relocated_upstream); @@ -458,7 +460,92 @@ PloverPackageSet * plover_transaction_helper_get_installed(PloverTransactionHelper *helper) { + gchar *s,*saved_database_uri; + char *install_root,*local_database,*active_database,*alternate_database; + const char *prefix; + struct comps *comps; + PloverPackageSet *alternate_installed,*installed; + GError *error=NULL; + struct razor_error *razor_error=NULL; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); + if (!helper->installed) + { + comps=plover_transaction_helper_get_comps(helper,NULL); + if (!comps) + { + g_warning("plover_transaction_helper_get_installed: No comps"); + return NULL; + } + install_root=getenv("RAZOR_ROOT"); + if (!install_root) + install_root="file:/"; + prefix=plover_transaction_helper_get_prefix(helper,NULL); + if (prefix) + { + s=g_strconcat(prefix,"/var/lib/razor",NULL); + local_database=razor_path_relative_to_uri(install_root,*s=='/'?s+1:s, + &razor_error); + g_free(s); + if (!local_database) + { + g_warning("plover_transaction_helper_get_installed: %s", + razor_error_get_msg(razor_error)); + razor_error_free(razor_error); + return NULL; + } + } + else + local_database=NULL; + switch(comps->database) + { + case COMPS_DATABASE_DISTRIBUTION_LOCAL: + active_database=local_database; + alternate_database=NULL; + break; + case COMPS_DATABASE_GLOBAL: + active_database=NULL; + alternate_database=local_database; + break; + } + saved_database_uri=g_strdup(razor_get_database_uri()); + if (prefix) + { + razor_set_database_uri(alternate_database); + alternate_installed=plover_package_set_new(); + if (!plover_package_set_open(alternate_installed,install_root,TRUE, + &error)) + { + g_object_unref(alternate_installed); + g_warning("plover_transaction_helper_get_installed: %s", + error->message); + g_error_free(error); + free(local_database); + razor_set_database_uri(saved_database_uri); + g_free(saved_database_uri); + return NULL; + } + } + else + alternate_installed=NULL; + razor_set_database_uri(active_database); + free(local_database); + installed=plover_package_set_new(); + if (plover_package_set_open(installed,install_root,TRUE,&error)) + { + helper->alternate_installed=alternate_installed; + helper->installed=installed; + } + else + { + g_object_unref(installed); + if (alternate_installed) + g_object_unref(alternate_installed); + g_warning("plover_transaction_helper_get_installed: %s",error->message); + g_error_free(error); + } + razor_set_database_uri(saved_database_uri); + g_free(saved_database_uri); + } return helper->installed; } @@ -468,6 +555,7 @@ g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper)); g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed)); g_return_if_fail(helper->installed == NULL); + g_clear_object(&helper->alternate_installed); helper->installed=g_object_ref(installed); } @@ -536,7 +624,7 @@ struct comps *comps; PloverTransactionHelperPrivate *priv; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); - g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL); + g_return_val_if_fail(helper->base != NULL || plover_transaction_helper_get_installed(helper) != NULL,NULL); priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); if (helper->base) { @@ -544,13 +632,14 @@ if (!comps) return NULL; g_free(priv->default_prefix); - priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor); + priv->default_prefix=plover_comps_get_default_prefix(comps); return priv->default_prefix; } prefix=plover_package_set_guess_prefix(helper->installed,error); return prefix; } +#if 0 static int plover_transaction_helper_package_count(void) { int count=0; @@ -572,44 +661,84 @@ } return count; } +#endif + +static gboolean prefix_clashes(const char *prefix,const char *alt) +{ + return g_str_has_prefix(prefix,alt) && + (prefix[strlen(alt)]=='\0' || prefix[strlen(alt)]=='/'); +} static gboolean plover_transaction_helper_check_vendor(PloverTransactionHelper *helper, GError **error) { - int i; + int i,remove_count=0; + gboolean alternate_database_clashes=FALSE; + gboolean active_database_is_incompatible=FALSE; + char *local_database,*active_database,*alternate_database; + const char *alternate_prefix; gchar *prefix=NULL,*s; struct comps *comps=NULL; GtkWidget *container,*summary,*page; GtkButton *button; GtkLabel *label; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); - if (helper->check_vendor) - { - comps=plover_transaction_helper_get_comps(helper,error); - if (!comps) - return FALSE; - prefix=plover_default_prefix_for_vendor(comps->vendor); - } + comps=plover_transaction_helper_get_comps(helper,error); + if (!comps) + return FALSE; + prefix=plover_comps_get_default_prefix(comps); button=GTK_BUTTON(gtk_builder_get_object(helper->ui,"SIRemoveExisting")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE); container=GTK_WIDGET(gtk_builder_get_object(helper->ui, "SIIncompatibleInstallation")); summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork")); page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm")); - if (helper->check_vendor && prefix && - !plover_installed_files_match_prefix(prefix)) + if (helper->check_vendor && prefix && helper->alternate_installed) + { + alternate_prefix= + plover_package_set_guess_prefix(helper->alternate_installed,NULL); + if (alternate_prefix && prefix_clashes(prefix,alternate_prefix)) + { + alternate_database_clashes=TRUE; + remove_count=g_slist_length( + plover_package_set_get_packages(helper->alternate_installed)); + } + } + /* + * Rather than try to be too clever, we only deal with one thing + * at a time. That means that if the alternate database clashes + * there's no point checking if the active database is compatible. + */ + if (!alternate_database_clashes) + { + if (helper->check_vendor && prefix && + !plover_package_set_files_match_prefix(helper->installed,prefix)) + { + active_database_is_incompatible=TRUE; + remove_count= + g_slist_length(plover_package_set_get_packages(helper->installed)); + } + } + if (alternate_database_clashes || active_database_is_incompatible) { label=GTK_LABEL(gtk_builder_get_object(helper->ui, "SIIncompatibleInstallationLabel")); - s=g_strdup_printf("Incompatible Installation\n\n" - "The existing installation is not from %s.\n" - "In order to continue, all the existing packages must be removed.", - comps->vendor); + if (alternate_database_clashes) + s=g_strdup_printf("Incompatible Installation\n\n" + "There is an existing installation under %s\n" + "which is not compatible with this distribution. In order\n" + "to continue, the existing installation must be uninstalled.", + comps->vendor); + else /* active_database_is_incompatible */ + s=g_strdup_printf("Incompatible Installation\n\n" + "The existing installation is not from %s.\n In order " + "to continue, all the existing packages must be removed.", + comps->vendor); gtk_label_set_markup(label,s); g_free(s); - i=plover_transaction_helper_package_count(); - s=g_strdup_printf("Remove %d existing package%s",i,i==1?"":"s"); + s=g_strdup_printf("Remove %d existing package%s",remove_count, + remove_count==1?"":"s"); gtk_button_set_label(button,s); g_free(s); gtk_widget_show(container); @@ -806,7 +935,7 @@ GError *tmp_error=NULL; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); - g_return_val_if_fail(helper->installed != NULL,NULL); + g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,NULL); prefix=plover_transaction_helper_get_prefix(helper,&tmp_error); if (tmp_error) { @@ -942,7 +1071,7 @@ struct plover_vector *selected_packages; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); - g_return_val_if_fail(helper->installed != NULL,FALSE); + g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,FALSE); selected_packages=plover_transaction_helper_group_get_default_packages( helper,group,error); if (!selected_packages)