1.1 --- a/plover-gtk/transactionhelper.c Tue Jun 28 15:55:48 2016 +0100
1.2 +++ b/plover-gtk/transactionhelper.c Tue Apr 24 20:58:03 2018 +0100
1.3 @@ -1,5 +1,5 @@
1.4 /*
1.5 - * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
1.6 + * Copyright (C) 2014, 2016 J. Ali Harlow <ali@juiblex.co.uk>
1.7 *
1.8 * This program is free software; you can redistribute it and/or modify
1.9 * it under the terms of the GNU General Public License as published by
1.10 @@ -18,6 +18,7 @@
1.11
1.12 #include "config.h"
1.13 #include <stdlib.h>
1.14 +#include <string.h>
1.15 #include <errno.h>
1.16 #include <gtk/gtk.h>
1.17 #include <plover/plover.h>
1.18 @@ -88,6 +89,7 @@
1.19 g_slist_foreach(helper->transactions,(GFunc)g_object_unref,NULL);
1.20 g_slist_free(helper->transactions);
1.21 helper->transactions=NULL;
1.22 + g_clear_object(&helper->alternate_installed);
1.23 g_clear_object(&helper->installed);
1.24 g_clear_object(&helper->upstream);
1.25 g_clear_object(&helper->relocated_upstream);
1.26 @@ -458,7 +460,92 @@
1.27 PloverPackageSet *
1.28 plover_transaction_helper_get_installed(PloverTransactionHelper *helper)
1.29 {
1.30 + gchar *s,*saved_database_uri;
1.31 + char *install_root,*local_database,*active_database,*alternate_database;
1.32 + const char *prefix;
1.33 + struct comps *comps;
1.34 + PloverPackageSet *alternate_installed,*installed;
1.35 + GError *error=NULL;
1.36 + struct razor_error *razor_error=NULL;
1.37 g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
1.38 + if (!helper->installed)
1.39 + {
1.40 + comps=plover_transaction_helper_get_comps(helper,NULL);
1.41 + if (!comps)
1.42 + {
1.43 + g_warning("plover_transaction_helper_get_installed: No comps");
1.44 + return NULL;
1.45 + }
1.46 + install_root=getenv("RAZOR_ROOT");
1.47 + if (!install_root)
1.48 + install_root="file:/";
1.49 + prefix=plover_transaction_helper_get_prefix(helper,NULL);
1.50 + if (prefix)
1.51 + {
1.52 + s=g_strconcat(prefix,"/var/lib/razor",NULL);
1.53 + local_database=razor_path_relative_to_uri(install_root,*s=='/'?s+1:s,
1.54 + &razor_error);
1.55 + g_free(s);
1.56 + if (!local_database)
1.57 + {
1.58 + g_warning("plover_transaction_helper_get_installed: %s",
1.59 + razor_error_get_msg(razor_error));
1.60 + razor_error_free(razor_error);
1.61 + return NULL;
1.62 + }
1.63 + }
1.64 + else
1.65 + local_database=NULL;
1.66 + switch(comps->database)
1.67 + {
1.68 + case COMPS_DATABASE_DISTRIBUTION_LOCAL:
1.69 + active_database=local_database;
1.70 + alternate_database=NULL;
1.71 + break;
1.72 + case COMPS_DATABASE_GLOBAL:
1.73 + active_database=NULL;
1.74 + alternate_database=local_database;
1.75 + break;
1.76 + }
1.77 + saved_database_uri=g_strdup(razor_get_database_uri());
1.78 + if (prefix)
1.79 + {
1.80 + razor_set_database_uri(alternate_database);
1.81 + alternate_installed=plover_package_set_new();
1.82 + if (!plover_package_set_open(alternate_installed,install_root,TRUE,
1.83 + &error))
1.84 + {
1.85 + g_object_unref(alternate_installed);
1.86 + g_warning("plover_transaction_helper_get_installed: %s",
1.87 + error->message);
1.88 + g_error_free(error);
1.89 + free(local_database);
1.90 + razor_set_database_uri(saved_database_uri);
1.91 + g_free(saved_database_uri);
1.92 + return NULL;
1.93 + }
1.94 + }
1.95 + else
1.96 + alternate_installed=NULL;
1.97 + razor_set_database_uri(active_database);
1.98 + free(local_database);
1.99 + installed=plover_package_set_new();
1.100 + if (plover_package_set_open(installed,install_root,TRUE,&error))
1.101 + {
1.102 + helper->alternate_installed=alternate_installed;
1.103 + helper->installed=installed;
1.104 + }
1.105 + else
1.106 + {
1.107 + g_object_unref(installed);
1.108 + if (alternate_installed)
1.109 + g_object_unref(alternate_installed);
1.110 + g_warning("plover_transaction_helper_get_installed: %s",error->message);
1.111 + g_error_free(error);
1.112 + }
1.113 + razor_set_database_uri(saved_database_uri);
1.114 + g_free(saved_database_uri);
1.115 + }
1.116 return helper->installed;
1.117 }
1.118
1.119 @@ -468,6 +555,7 @@
1.120 g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
1.121 g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed));
1.122 g_return_if_fail(helper->installed == NULL);
1.123 + g_clear_object(&helper->alternate_installed);
1.124 helper->installed=g_object_ref(installed);
1.125 }
1.126
1.127 @@ -536,7 +624,7 @@
1.128 struct comps *comps;
1.129 PloverTransactionHelperPrivate *priv;
1.130 g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
1.131 - g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL);
1.132 + g_return_val_if_fail(helper->base != NULL || plover_transaction_helper_get_installed(helper) != NULL,NULL);
1.133 priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
1.134 if (helper->base)
1.135 {
1.136 @@ -544,13 +632,14 @@
1.137 if (!comps)
1.138 return NULL;
1.139 g_free(priv->default_prefix);
1.140 - priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor);
1.141 + priv->default_prefix=plover_comps_get_default_prefix(comps);
1.142 return priv->default_prefix;
1.143 }
1.144 prefix=plover_package_set_guess_prefix(helper->installed,error);
1.145 return prefix;
1.146 }
1.147
1.148 +#if 0
1.149 static int plover_transaction_helper_package_count(void)
1.150 {
1.151 int count=0;
1.152 @@ -572,44 +661,84 @@
1.153 }
1.154 return count;
1.155 }
1.156 +#endif
1.157 +
1.158 +static gboolean prefix_clashes(const char *prefix,const char *alt)
1.159 +{
1.160 + return g_str_has_prefix(prefix,alt) &&
1.161 + (prefix[strlen(alt)]=='\0' || prefix[strlen(alt)]=='/');
1.162 +}
1.163
1.164 static gboolean
1.165 plover_transaction_helper_check_vendor(PloverTransactionHelper *helper,
1.166 GError **error)
1.167 {
1.168 - int i;
1.169 + int i,remove_count=0;
1.170 + gboolean alternate_database_clashes=FALSE;
1.171 + gboolean active_database_is_incompatible=FALSE;
1.172 + char *local_database,*active_database,*alternate_database;
1.173 + const char *alternate_prefix;
1.174 gchar *prefix=NULL,*s;
1.175 struct comps *comps=NULL;
1.176 GtkWidget *container,*summary,*page;
1.177 GtkButton *button;
1.178 GtkLabel *label;
1.179 g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
1.180 - if (helper->check_vendor)
1.181 - {
1.182 - comps=plover_transaction_helper_get_comps(helper,error);
1.183 - if (!comps)
1.184 - return FALSE;
1.185 - prefix=plover_default_prefix_for_vendor(comps->vendor);
1.186 - }
1.187 + comps=plover_transaction_helper_get_comps(helper,error);
1.188 + if (!comps)
1.189 + return FALSE;
1.190 + prefix=plover_comps_get_default_prefix(comps);
1.191 button=GTK_BUTTON(gtk_builder_get_object(helper->ui,"SIRemoveExisting"));
1.192 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
1.193 container=GTK_WIDGET(gtk_builder_get_object(helper->ui,
1.194 "SIIncompatibleInstallation"));
1.195 summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork"));
1.196 page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm"));
1.197 - if (helper->check_vendor && prefix &&
1.198 - !plover_installed_files_match_prefix(prefix))
1.199 + if (helper->check_vendor && prefix && helper->alternate_installed)
1.200 + {
1.201 + alternate_prefix=
1.202 + plover_package_set_guess_prefix(helper->alternate_installed,NULL);
1.203 + if (alternate_prefix && prefix_clashes(prefix,alternate_prefix))
1.204 + {
1.205 + alternate_database_clashes=TRUE;
1.206 + remove_count=g_slist_length(
1.207 + plover_package_set_get_packages(helper->alternate_installed));
1.208 + }
1.209 + }
1.210 + /*
1.211 + * Rather than try to be too clever, we only deal with one thing
1.212 + * at a time. That means that if the alternate database clashes
1.213 + * there's no point checking if the active database is compatible.
1.214 + */
1.215 + if (!alternate_database_clashes)
1.216 + {
1.217 + if (helper->check_vendor && prefix &&
1.218 + !plover_package_set_files_match_prefix(helper->installed,prefix))
1.219 + {
1.220 + active_database_is_incompatible=TRUE;
1.221 + remove_count=
1.222 + g_slist_length(plover_package_set_get_packages(helper->installed));
1.223 + }
1.224 + }
1.225 + if (alternate_database_clashes || active_database_is_incompatible)
1.226 {
1.227 label=GTK_LABEL(gtk_builder_get_object(helper->ui,
1.228 "SIIncompatibleInstallationLabel"));
1.229 - s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
1.230 - "The existing installation is not from %s.\n"
1.231 - "In order to continue, all the existing packages must be removed.",
1.232 - comps->vendor);
1.233 + if (alternate_database_clashes)
1.234 + s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
1.235 + "There is an existing installation under %s\n"
1.236 + "which is not compatible with this distribution. In order\n"
1.237 + "to continue, the existing installation must be uninstalled.",
1.238 + comps->vendor);
1.239 + else /* active_database_is_incompatible */
1.240 + s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
1.241 + "The existing installation is not from %s.\n In order "
1.242 + "to continue, all the existing packages must be removed.",
1.243 + comps->vendor);
1.244 gtk_label_set_markup(label,s);
1.245 g_free(s);
1.246 - i=plover_transaction_helper_package_count();
1.247 - s=g_strdup_printf("Remove %d existing package%s",i,i==1?"":"s");
1.248 + s=g_strdup_printf("Remove %d existing package%s",remove_count,
1.249 + remove_count==1?"":"s");
1.250 gtk_button_set_label(button,s);
1.251 g_free(s);
1.252 gtk_widget_show(container);
1.253 @@ -806,7 +935,7 @@
1.254 GError *tmp_error=NULL;
1.255 PloverTransaction *transaction;
1.256 g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
1.257 - g_return_val_if_fail(helper->installed != NULL,NULL);
1.258 + g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,NULL);
1.259 prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
1.260 if (tmp_error)
1.261 {
1.262 @@ -942,7 +1071,7 @@
1.263 struct plover_vector *selected_packages;
1.264 PloverTransaction *transaction;
1.265 g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
1.266 - g_return_val_if_fail(helper->installed != NULL,FALSE);
1.267 + g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,FALSE);
1.268 selected_packages=plover_transaction_helper_group_get_default_packages(
1.269 helper,group,error);
1.270 if (!selected_packages)