plover-gtk/transactionhelper.c
changeset 65 d1433cd15271
parent 50 a4f43ad0e0c8
child 75 6575679d2e8e
     1.1 --- a/plover-gtk/transactionhelper.c	Tue Jun 28 15:55:48 2016 +0100
     1.2 +++ b/plover-gtk/transactionhelper.c	Fri Mar 02 17:17:58 2018 +0000
     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)