Support parallel installations. The idea is that for CAD screener, we want
authorJ. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 6131fb35727621
parent 60 772ff096a326
child 62 5c3ef7363959
Support parallel installations. The idea is that for CAD screener, we want
to be able to install this on the same machine as a standard AVOT setup
(most notably for John's laptop). To allow for the possibility of a second
application that might have the same requirements, we add the concept of
vendor-specific distributions. Thus we can have one distribution for CAD
screener and one for The Next Big Thing. It doesn't seem trivial to have
both CAD screener and AVOT under the same vendor tag so we'll have to have
AVOT under "City Occupational" and CAD screener under "City Occupational Ltd"
or some such kludge.

Most of this is done although we are very short of test cases (in particular
we don't test that it's actually possible to install CAD screener in parallel
with AVOT or to update either of them once installed, which is fundamental).

We also have a lot of baggage left over, including an intercept of razor_set.
The problem that this was introduced to debug has been fixed but it looks
like there are a number of memory leaks which it might be useful to help
track down so it has been left in place for now.

There is still a lot of confusion in plover between path-based and URI-based
API. We should review the API, decide what we want and have a general clear up.

There is also confusion as to the purpose of RAZOR_ROOT (and meaning; path or
URI). This is not used at all in librazor (although it is used in razor.exe).
Ideally we shouldn't use it in plover or plover-gtk either although again, we
might want to support it or an equivalent in (some of) the various executables.

Work that would still to nice to do for CAD screener:

- uninstall (ideally as an installed program that hooks into Add/Remove programs
but even re-running the installer would be acceptable).
- xz support (smaller packages).
- repomd.xml and xml:base (would be needed for an Internet installer).
- graphical installer.
app-manager/app-manager.c
app-manager/app-manager.h
app-manager/setup.c
app-manager/update.c
configure.ac
plover-gtk/transactionhelper.c
plover-gtk/transactionhelper.h
plover/Makefile.am
plover/comps.c
plover/import-yum.c
plover/inputstream.c
plover/inputstream.h
plover/packageset.c
plover/packageset.h
plover/plover.h
plover/razor.c
plover/transaction.c
plover/util.c
setup/setup.c
tests/Makefile.am
tests/plover-gtk/test-transactionhelper.c
tests/plover/test-packageset.c
tests/plover/test-transaction.c
tests/plover/test-uri-handler.c
update/Makefile.am
update/manifest.xml.in
update/resources.rc.in
update/update-res.rc.in
update/update.c
update/update.manifest.in
update/updatez-res.rc.in
update/updatez.c
update/updatez.manifest.in
     1.1 --- a/app-manager/app-manager.c	Fri Jul 08 08:33:44 2016 +0100
     1.2 +++ b/app-manager/app-manager.c	Sat Jul 16 11:07:18 2016 +0100
     1.3 @@ -215,17 +215,20 @@
     1.4  {
     1.5      GError *err=0;
     1.6      GtkWidget *w;
     1.7 -    gchar *s,*contents;
     1.8 -    gchar *setup_base=NULL,*update_base=NULL;
     1.9 +    gchar *s,*database_uri,*contents;
    1.10 +    gchar *database=NULL,*setup_base=NULL,*update_base=NULL;
    1.11      gsize len;
    1.12 -    PloverPackageSet *set;
    1.13 +    struct comps *comps;
    1.14 +    PloverPackageSet *set=NULL;
    1.15      GSList *objects,*lnk;
    1.16      gboolean started;
    1.17      GOptionEntry options[]={
    1.18 -	{"setup",0,0,G_OPTION_ARG_FILENAME,&setup_base,
    1.19 -	  "Setup from installation media","path"},
    1.20 -	{"update",0,0,G_OPTION_ARG_FILENAME,&update_base,
    1.21 -	  "Update from upgrade media","path"},
    1.22 +	{"database",0,0,G_OPTION_ARG_STRING,&database,
    1.23 +	  "Operate on a distribution-local database","vendor/distribution"},
    1.24 +	{"setup",0,0,G_OPTION_ARG_STRING,&setup_base,
    1.25 +	  "Setup from installation media","uri"},
    1.26 +	{"update",0,0,G_OPTION_ARG_STRING,&update_base,
    1.27 +	  "Update from upgrade media","uri"},
    1.28  	{NULL}
    1.29      };
    1.30  #ifdef WIN32
    1.31 @@ -285,30 +288,52 @@
    1.32  	g_error("%s",err->message);
    1.33  	exit(0);
    1.34      }
    1.35 -    if (prefix)
    1.36 -    {
    1.37 -	relocations=razor_relocations_create();
    1.38 -	razor_relocations_add(relocations,"/usr",prefix);
    1.39 -    }
    1.40      gtk_builder_connect_signals(ui,NULL);
    1.41      gtk_link_button_set_uri_hook(show_uri,NULL,NULL);
    1.42 -    installed=GTK_TREE_MODEL(plover_package_store_new());
    1.43 -    set=plover_package_set_new();
    1.44 -    (void)plover_package_set_open(set,"",TRUE,NULL);
    1.45 -    plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set);
    1.46 -    if (plover_package_set_get_no_details(set))
    1.47 -    {
    1.48 -	w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles"));
    1.49 -	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE);
    1.50 -    }
    1.51 -    applications=plover_applications_model_new(installed);
    1.52 -    set_package_model(applications);
    1.53      if (setup_base)
    1.54 -	started=setup(set,setup_base);
    1.55 +	started=setup(setup_base);
    1.56      else if (update_base)
    1.57 -	started=update(set,update_base);
    1.58 +	started=update(update_base);
    1.59      else
    1.60      {
    1.61 +	if (database)
    1.62 +	{
    1.63 +	    g_free(prefix);
    1.64 +	    prefix=NULL;
    1.65 +	    s=strchr(database,'/');
    1.66 +	    if (*s)
    1.67 +		*s++='\0';
    1.68 +	    comps=plover_comps_new();
    1.69 +	    plover_comps_set_vendor(comps,database);
    1.70 +	    if (s)
    1.71 +	    {
    1.72 +		plover_comps_set_distribution(comps,s);
    1.73 +		*--s='/';
    1.74 +	    }
    1.75 +	    prefix=plover_comps_get_default_prefix(comps);
    1.76 +	    plover_comps_free(comps);
    1.77 +	    s=g_strconcat(prefix,"/var/lib/razor",NULL);
    1.78 +	    database_uri=razor_path_to_uri(s);
    1.79 +	    g_free(s);
    1.80 +	    razor_set_database_uri(database_uri);
    1.81 +	    g_free(database_uri);
    1.82 +	}
    1.83 +	if (prefix)
    1.84 +	{
    1.85 +	    relocations=razor_relocations_create();
    1.86 +	    razor_relocations_add(relocations,"/usr",prefix);
    1.87 +	}
    1.88 +	installed=GTK_TREE_MODEL(plover_package_store_new());
    1.89 +	set=plover_package_set_new();
    1.90 +	(void)plover_package_set_open(set,"",TRUE,NULL);
    1.91 +	plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set);
    1.92 +	if (plover_package_set_get_no_details(set))
    1.93 +	{
    1.94 +	    w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles"));
    1.95 +	    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE);
    1.96 +	}
    1.97 +	applications=plover_applications_model_new(installed);
    1.98 +	set_package_model(applications);
    1.99  	w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
   1.100  	gtk_widget_show(w);
   1.101  	started=TRUE;
   1.102 @@ -332,6 +357,7 @@
   1.103      g_free(prefix);
   1.104      g_free(setup_base);
   1.105      g_free(update_base);
   1.106 +    g_free(database);
   1.107      exit(0);
   1.108  }
   1.109  
     2.1 --- a/app-manager/app-manager.h	Fri Jul 08 08:33:44 2016 +0100
     2.2 +++ b/app-manager/app-manager.h	Sat Jul 16 11:07:18 2016 +0100
     2.3 @@ -7,5 +7,5 @@
     2.4  GtkTreeModel *plover_applications_model_new(GtkTreeModel *installed);
     2.5  void set_package_model(GtkTreeModel *model);
     2.6  PloverPackage *get_active_package(void);
     2.7 -gboolean setup(PloverPackageSet *current,const char *base);
     2.8 -gboolean update(PloverPackageSet *current,const char *base);
     2.9 +gboolean setup(const char *base);
    2.10 +gboolean update(const char *base);
     3.1 --- a/app-manager/setup.c	Fri Jul 08 08:33:44 2016 +0100
     3.2 +++ b/app-manager/setup.c	Sat Jul 16 11:07:18 2016 +0100
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (C) 2014  J. Ali Harlow <ali@juiblex.co.uk>
     3.6 + * Copyright (C) 2014, 2016  J. Ali Harlow <ali@juiblex.co.uk>
     3.7   *
     3.8   * This program is free software; you can redistribute it and/or modify
     3.9   * it under the terms of the GNU General Public License as published by
    3.10 @@ -29,7 +29,7 @@
    3.11  #include <plover-gtk/transactionhelper.h>
    3.12  #include "app-manager.h"
    3.13  
    3.14 -gboolean setup(PloverPackageSet *installed,const char *base)
    3.15 +gboolean setup(const char *base)
    3.16  {
    3.17      gchar *s;
    3.18      const char *prefix;
    3.19 @@ -38,7 +38,6 @@
    3.20      if (!helper)
    3.21      {
    3.22  	helper=plover_transaction_helper_new(ui);
    3.23 -	plover_transaction_helper_set_installed(helper,installed);
    3.24  	plover_transaction_helper_set_base(helper,base);
    3.25  	prefix=plover_transaction_helper_get_prefix(helper,&error);
    3.26  	if (error)
     4.1 --- a/app-manager/update.c	Fri Jul 08 08:33:44 2016 +0100
     4.2 +++ b/app-manager/update.c	Sat Jul 16 11:07:18 2016 +0100
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (C) 2014  J. Ali Harlow <ali@juiblex.co.uk>
     4.6 + * Copyright (C) 2014, 2016  J. Ali Harlow <ali@juiblex.co.uk>
     4.7   *
     4.8   * This program is free software; you can redistribute it and/or modify
     4.9   * it under the terms of the GNU General Public License as published by
    4.10 @@ -29,16 +29,16 @@
    4.11  #include <plover-gtk/transactionhelper.h>
    4.12  #include "app-manager.h"
    4.13  
    4.14 -gboolean update(PloverPackageSet *installed,const char *base)
    4.15 +
    4.16 +gboolean update(const char *base)
    4.17  {
    4.18 -    gchar *s;
    4.19 +    gchar *s,*database_uri;
    4.20      const char *prefix;
    4.21      GError *error=NULL;
    4.22      static PloverTransactionHelper *helper=NULL;
    4.23      if (!helper)
    4.24      {
    4.25  	helper=plover_transaction_helper_new(ui);
    4.26 -	plover_transaction_helper_set_installed(helper,installed);
    4.27  	plover_transaction_helper_set_base(helper,base);
    4.28  	prefix=plover_transaction_helper_get_prefix(helper,&error);
    4.29  	if (error)
     5.1 --- a/configure.ac	Fri Jul 08 08:33:44 2016 +0100
     5.2 +++ b/configure.ac	Sat Jul 16 11:07:18 2016 +0100
     5.3 @@ -15,8 +15,7 @@
     5.4  setup/Makefile
     5.5  setup/resources.rc
     5.6  update/Makefile
     5.7 -update/update-res.rc
     5.8 -update/updatez-res.rc
     5.9 +update/resources.rc
    5.10  pre-inst/Makefile
    5.11  pre-inst/resources.rc
    5.12  app-manager/Makefile
    5.13 @@ -28,8 +27,7 @@
    5.14  tests/plover-gtk/Makefile
    5.15  ])
    5.16  PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in
    5.17 -update/update.exe.manifest:update/update.manifest.in
    5.18 -update/updatez.exe.manifest:update/updatez.manifest.in
    5.19 +update/update.exe.manifest:update/manifest.xml.in
    5.20  pre-inst/pre-inst.exe.manifest:pre-inst/manifest.xml.in
    5.21  app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in
    5.22  plover-open/plover-open.exe.manifest:plover-open/manifest.xml.in
     6.1 --- a/plover-gtk/transactionhelper.c	Fri Jul 08 08:33:44 2016 +0100
     6.2 +++ b/plover-gtk/transactionhelper.c	Sat Jul 16 11:07:18 2016 +0100
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (C) 2014  J. Ali Harlow <ali@juiblex.co.uk>
     6.6 + * Copyright (C) 2014, 2016  J. Ali Harlow <ali@juiblex.co.uk>
     6.7   *
     6.8   * This program is free software; you can redistribute it and/or modify
     6.9   * it under the terms of the GNU General Public License as published by
    6.10 @@ -18,6 +18,7 @@
    6.11  
    6.12  #include "config.h"
    6.13  #include <stdlib.h>
    6.14 +#include <string.h>
    6.15  #include <errno.h>
    6.16  #include <gtk/gtk.h>
    6.17  #include <plover/plover.h>
    6.18 @@ -88,6 +89,7 @@
    6.19      g_slist_foreach(helper->transactions,(GFunc)g_object_unref,NULL);
    6.20      g_slist_free(helper->transactions);
    6.21      helper->transactions=NULL;
    6.22 +    g_clear_object(&helper->alternate_installed);
    6.23      g_clear_object(&helper->installed);
    6.24      g_clear_object(&helper->upstream);
    6.25      g_clear_object(&helper->relocated_upstream);
    6.26 @@ -458,7 +460,92 @@
    6.27  PloverPackageSet *
    6.28    plover_transaction_helper_get_installed(PloverTransactionHelper *helper)
    6.29  {
    6.30 +    gchar *s,*saved_database_uri;
    6.31 +    char *install_root,*local_database,*active_database,*alternate_database;
    6.32 +    const char *prefix;
    6.33 +    struct comps *comps;
    6.34 +    PloverPackageSet *alternate_installed,*installed;
    6.35 +    GError *error=NULL;
    6.36 +    struct razor_error *razor_error=NULL;
    6.37      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
    6.38 +    if (!helper->installed)
    6.39 +    {
    6.40 +	comps=plover_transaction_helper_get_comps(helper,NULL);
    6.41 +	if (!comps)
    6.42 +	{
    6.43 +	    g_warning("plover_transaction_helper_get_installed: No comps");
    6.44 +	    return NULL;
    6.45 +	}
    6.46 +	install_root=getenv("RAZOR_ROOT");
    6.47 +	if (!install_root)
    6.48 +	    install_root="file:/";
    6.49 +	prefix=plover_transaction_helper_get_prefix(helper,NULL);
    6.50 +	if (prefix)
    6.51 +	{
    6.52 +	    s=g_strconcat(prefix,"/var/lib/razor",NULL);
    6.53 +	    local_database=razor_path_relative_to_uri(install_root,*s=='/'?s+1:s,
    6.54 +	      &razor_error);
    6.55 +	    g_free(s);
    6.56 +	    if (!local_database)
    6.57 +	    {
    6.58 +		g_warning("plover_transaction_helper_get_installed: %s",
    6.59 +		  razor_error_get_msg(razor_error));
    6.60 +		razor_error_free(razor_error);
    6.61 +		return NULL;
    6.62 +	    }
    6.63 +	}
    6.64 +	else
    6.65 +	    local_database=NULL;
    6.66 +	switch(comps->database)
    6.67 +	{
    6.68 +	    case COMPS_DATABASE_DISTRIBUTION_LOCAL:
    6.69 +		active_database=local_database;
    6.70 +		alternate_database=NULL;
    6.71 +		break;
    6.72 +	    case COMPS_DATABASE_GLOBAL:
    6.73 +		active_database=NULL;
    6.74 +		alternate_database=local_database;
    6.75 +		break;
    6.76 +	}
    6.77 +	saved_database_uri=g_strdup(razor_get_database_uri());
    6.78 +	if (prefix)
    6.79 +	{
    6.80 +	    razor_set_database_uri(alternate_database);
    6.81 +	    alternate_installed=plover_package_set_new();
    6.82 +	    if (!plover_package_set_open(alternate_installed,install_root,TRUE,
    6.83 +	      &error))
    6.84 +	    {
    6.85 +		g_object_unref(alternate_installed);
    6.86 +		g_warning("plover_transaction_helper_get_installed: %s",
    6.87 +		  error->message);
    6.88 +		g_error_free(error);
    6.89 +		free(local_database);
    6.90 +		razor_set_database_uri(saved_database_uri);
    6.91 +		g_free(saved_database_uri);
    6.92 +		return NULL;
    6.93 +	    }
    6.94 +	}
    6.95 +	else
    6.96 +	    alternate_installed=NULL;
    6.97 +	razor_set_database_uri(active_database);
    6.98 +	free(local_database);
    6.99 +	installed=plover_package_set_new();
   6.100 +	if (plover_package_set_open(installed,install_root,TRUE,&error))
   6.101 +	{
   6.102 +	    helper->alternate_installed=alternate_installed;
   6.103 +	    helper->installed=installed;
   6.104 +	}
   6.105 +	else
   6.106 +	{
   6.107 +	    g_object_unref(installed);
   6.108 +	    if (alternate_installed)
   6.109 +		g_object_unref(alternate_installed);
   6.110 +	    g_warning("plover_transaction_helper_get_installed: %s",error->message);
   6.111 +	    g_error_free(error);
   6.112 +	}
   6.113 +	razor_set_database_uri(saved_database_uri);
   6.114 +	g_free(saved_database_uri);
   6.115 +    }
   6.116      return helper->installed;
   6.117  }
   6.118  
   6.119 @@ -468,6 +555,7 @@
   6.120      g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
   6.121      g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed));
   6.122      g_return_if_fail(helper->installed == NULL);
   6.123 +    g_clear_object(&helper->alternate_installed);
   6.124      helper->installed=g_object_ref(installed);
   6.125  }
   6.126  
   6.127 @@ -536,7 +624,7 @@
   6.128      struct comps *comps;
   6.129      PloverTransactionHelperPrivate *priv;
   6.130      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
   6.131 -    g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL);
   6.132 +    g_return_val_if_fail(helper->base != NULL || plover_transaction_helper_get_installed(helper) != NULL,NULL);
   6.133      priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
   6.134      if (helper->base)
   6.135      {
   6.136 @@ -544,13 +632,14 @@
   6.137  	if (!comps)
   6.138  	    return NULL;
   6.139  	g_free(priv->default_prefix);
   6.140 -	priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor);
   6.141 +	priv->default_prefix=plover_comps_get_default_prefix(comps);
   6.142  	return priv->default_prefix;
   6.143      }
   6.144      prefix=plover_package_set_guess_prefix(helper->installed,error);
   6.145      return prefix;
   6.146  }
   6.147  
   6.148 +#if 0
   6.149  static int plover_transaction_helper_package_count(void)
   6.150  {
   6.151      int count=0;
   6.152 @@ -572,44 +661,84 @@
   6.153      }
   6.154      return count;
   6.155  }
   6.156 +#endif
   6.157 +
   6.158 +static gboolean prefix_clashes(const char *prefix,const char *alt)
   6.159 +{
   6.160 +    return g_str_has_prefix(prefix,alt) &&
   6.161 +      (prefix[strlen(alt)]=='\0' || prefix[strlen(alt)]=='/');
   6.162 +}
   6.163  
   6.164  static gboolean
   6.165    plover_transaction_helper_check_vendor(PloverTransactionHelper *helper,
   6.166    GError **error)
   6.167  {
   6.168 -    int i;
   6.169 +    int i,remove_count=0;
   6.170 +    gboolean alternate_database_clashes=FALSE;
   6.171 +    gboolean active_database_is_incompatible=FALSE;
   6.172 +    char *local_database,*active_database,*alternate_database;
   6.173 +    const char *alternate_prefix;
   6.174      gchar *prefix=NULL,*s;
   6.175      struct comps *comps=NULL;
   6.176      GtkWidget *container,*summary,*page;
   6.177      GtkButton *button;
   6.178      GtkLabel *label;
   6.179      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
   6.180 -    if (helper->check_vendor)
   6.181 -    {
   6.182 -	comps=plover_transaction_helper_get_comps(helper,error);
   6.183 -	if (!comps)
   6.184 -	    return FALSE;
   6.185 -	prefix=plover_default_prefix_for_vendor(comps->vendor);
   6.186 -    }
   6.187 +    comps=plover_transaction_helper_get_comps(helper,error);
   6.188 +    if (!comps)
   6.189 +	return FALSE;
   6.190 +    prefix=plover_comps_get_default_prefix(comps);
   6.191      button=GTK_BUTTON(gtk_builder_get_object(helper->ui,"SIRemoveExisting"));
   6.192      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
   6.193      container=GTK_WIDGET(gtk_builder_get_object(helper->ui,
   6.194        "SIIncompatibleInstallation"));
   6.195      summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork"));
   6.196      page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm"));
   6.197 -    if (helper->check_vendor && prefix &&
   6.198 -      !plover_installed_files_match_prefix(prefix))
   6.199 +    if (helper->check_vendor && prefix && helper->alternate_installed)
   6.200 +    {
   6.201 +	alternate_prefix=
   6.202 +	  plover_package_set_guess_prefix(helper->alternate_installed,NULL);
   6.203 +	if (alternate_prefix && prefix_clashes(prefix,alternate_prefix))
   6.204 +	{
   6.205 +	    alternate_database_clashes=TRUE;
   6.206 +	    remove_count=g_slist_length(
   6.207 +	      plover_package_set_get_packages(helper->alternate_installed));
   6.208 +	}
   6.209 +    }
   6.210 +    /*
   6.211 +     * Rather than try to be too clever, we only deal with one thing
   6.212 +     * at a time. That means that if the alternate database clashes
   6.213 +     * there's no point checking if the active database is compatible.
   6.214 +     */
   6.215 +    if (!alternate_database_clashes)
   6.216 +    {
   6.217 +	if (helper->check_vendor && prefix &&
   6.218 +	  !plover_package_set_files_match_prefix(helper->installed,prefix))
   6.219 +	{
   6.220 +	    active_database_is_incompatible=TRUE;
   6.221 +	    remove_count=
   6.222 +	      g_slist_length(plover_package_set_get_packages(helper->installed));
   6.223 +	}
   6.224 +    }
   6.225 +    if (alternate_database_clashes || active_database_is_incompatible)
   6.226      {
   6.227  	label=GTK_LABEL(gtk_builder_get_object(helper->ui,
   6.228  	  "SIIncompatibleInstallationLabel"));
   6.229 -	s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
   6.230 -	  "The existing installation is not from %s.\n"
   6.231 -	  "In order to continue, all the existing packages must be removed.",
   6.232 -	  comps->vendor);
   6.233 +	if (alternate_database_clashes)
   6.234 +	    s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
   6.235 +	      "There is an existing installation under %s\n"
   6.236 +	      "which is not compatible with this distribution. In order\n"
   6.237 +	      "to continue, the existing installation must be uninstalled.",
   6.238 +	      comps->vendor);
   6.239 +	else /* active_database_is_incompatible */
   6.240 +	    s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
   6.241 +	      "The existing installation is not from %s.\n In order "
   6.242 +	      "to continue, all the existing packages must be removed.",
   6.243 +	      comps->vendor);
   6.244  	gtk_label_set_markup(label,s);
   6.245  	g_free(s);
   6.246 -	i=plover_transaction_helper_package_count();
   6.247 -	s=g_strdup_printf("Remove %d existing package%s",i,i==1?"":"s");
   6.248 +	s=g_strdup_printf("Remove %d existing package%s",remove_count,
   6.249 +	  remove_count==1?"":"s");
   6.250  	gtk_button_set_label(button,s);
   6.251  	g_free(s);
   6.252  	gtk_widget_show(container);
   6.253 @@ -806,7 +935,7 @@
   6.254      GError *tmp_error=NULL;
   6.255      PloverTransaction *transaction;
   6.256      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
   6.257 -    g_return_val_if_fail(helper->installed != NULL,NULL);
   6.258 +    g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,NULL);
   6.259      prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
   6.260      if (tmp_error)
   6.261      {
   6.262 @@ -942,7 +1071,7 @@
   6.263      struct plover_vector *selected_packages;
   6.264      PloverTransaction *transaction;
   6.265      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
   6.266 -    g_return_val_if_fail(helper->installed != NULL,FALSE);
   6.267 +    g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,FALSE);
   6.268      selected_packages=plover_transaction_helper_group_get_default_packages(
   6.269        helper,group,error);
   6.270      if (!selected_packages)
     7.1 --- a/plover-gtk/transactionhelper.h	Fri Jul 08 08:33:44 2016 +0100
     7.2 +++ b/plover-gtk/transactionhelper.h	Sat Jul 16 11:07:18 2016 +0100
     7.3 @@ -33,7 +33,7 @@
     7.4  
     7.5  typedef struct _PloverTransactionHelper {
     7.6      GObject parent_instance;
     7.7 -    PloverPackageSet *installed;
     7.8 +    PloverPackageSet *alternate_installed,*installed;
     7.9      PloverRepository *upstream;
    7.10      PloverPackageSet *relocated_upstream;
    7.11      gchar *base;
     8.1 --- a/plover/Makefile.am	Fri Jul 08 08:33:44 2016 +0100
     8.2 +++ b/plover/Makefile.am	Sat Jul 16 11:07:18 2016 +0100
     8.3 @@ -5,12 +5,13 @@
     8.4  AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO) \
     8.5    $(CODE_COVERAGE_LDFLAGS) -export-symbols-regex '^plover_[^_]'
     8.6  
     8.7 -pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h
     8.8 +pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h \
     8.9 +	inputstream.h
    8.10  
    8.11  lib_LTLIBRARIES=libplover.la
    8.12  libplover_la_SOURCES=$(pkginclude_HEADERS) util.c import-yum.c razor.c comps.c \
    8.13  	log.c vector.c transaction.c package.c packageset.c repository.c \
    8.14 -	uri-handler.c uri-handler.h exception-handler.cpp
    8.15 +	uri-handler.c uri-handler.h inputstream.c exception-handler.cpp
    8.16  
    8.17  pkgconfigdir=$(libdir)/pkgconfig
    8.18  pkgconfig_DATA=plover.pc
     9.1 --- a/plover/comps.c	Fri Jul 08 08:33:44 2016 +0100
     9.2 +++ b/plover/comps.c	Sat Jul 16 11:07:18 2016 +0100
     9.3 @@ -28,6 +28,8 @@
     9.4  
     9.5  /* Parse a comps.xml package group file. */
     9.6  
     9.7 +#define PLOVER_XML_NS "http://project.juiblex.co.uk/plover/ns/2009"
     9.8 +
     9.9  static struct comps_requirement *comps_package_requirement_new(void)
    9.10  {
    9.11      struct comps_requirement *req;
    9.12 @@ -104,6 +106,7 @@
    9.13      if (comps)
    9.14      {
    9.15  	free(comps->vendor);
    9.16 +	free(comps->distribution);
    9.17  	comps_group_free(comps->groups);
    9.18  	free(comps);
    9.19      }
    9.20 @@ -126,7 +129,8 @@
    9.21      XML_Parser parser;
    9.22      enum comps_state state;
    9.23      int unknown_elements;
    9.24 -    char *vendor;
    9.25 +    char *vendor,*distribution;
    9.26 +    enum comps_database_setting database;
    9.27      struct comps_group *group;
    9.28      void *p;
    9.29  };
    9.30 @@ -196,9 +200,17 @@
    9.31  	ctx->state=COMPS_STATE_ROOT;
    9.32  	for (i=0;atts[i];i+=2)
    9.33  	{
    9.34 -	    if (!strcmp(atts[i],
    9.35 -	      "http://project.juiblex.co.uk/plover/ns/2009\xFFvendor"))
    9.36 +	    if (!strcmp(atts[i],PLOVER_XML_NS "\xFF" "vendor"))
    9.37  		ctx->vendor=strdup(atts[i+1]);
    9.38 +	    else if (!strcmp(atts[i],PLOVER_XML_NS "\xFF" "distribution"))
    9.39 +		ctx->distribution=strdup(atts[i+1]);
    9.40 +	    else if (!strcmp(atts[i],PLOVER_XML_NS "\xFF" "database"))
    9.41 +	    {
    9.42 +		if (!g_strcmp0(atts[i+1],"distribution-local"))
    9.43 +		    ctx->database=COMPS_DATABASE_DISTRIBUTION_LOCAL;
    9.44 +		else
    9.45 +		    ctx->database=COMPS_DATABASE_GLOBAL;
    9.46 +	    }
    9.47  	}
    9.48      }
    9.49      else if (ctx->state==COMPS_STATE_ROOT && !strcmp(name,"group"))
    9.50 @@ -371,64 +383,47 @@
    9.51      }
    9.52  }
    9.53  
    9.54 -#define XML_BUFFER_SIZE 4096
    9.55 -
    9.56 -struct comps *plover_comps_new_from_uri(const char *uri)
    9.57 +struct comps *plover_comps_new_from_uri(const char *uri,GError **error)
    9.58  {
    9.59      struct comps_context ctx={0};
    9.60 -    void *buf;
    9.61 -    gssize len;
    9.62 -    GFile *file;
    9.63 -    GFileInputStream *stream;
    9.64 -    XML_ParsingStatus status;
    9.65 +    struct razor_error *tmp_error=NULL;
    9.66 +    void *contents;
    9.67 +    size_t length;
    9.68      struct comps *comps;
    9.69      plover__uri_handler_init();
    9.70 -    file=g_file_new_for_uri(uri);
    9.71 -    stream=g_file_read(file,NULL,NULL);
    9.72 -    g_object_unref(file);
    9.73 -    if (!stream)
    9.74 +    contents=razor_uri_get_contents(uri,&length,FALSE,&tmp_error);
    9.75 +    if (!contents)
    9.76 +    {
    9.77 +	plover_propagate_razor_error(error,tmp_error);
    9.78  	return NULL;
    9.79 +    }
    9.80      ctx.state=COMPS_STATE_BEGIN;
    9.81      ctx.parser=XML_ParserCreateNS(NULL,'\xFF');
    9.82      XML_SetUserData(ctx.parser,&ctx);
    9.83      XML_SetElementHandler(ctx.parser,comps_start_element,comps_end_element);
    9.84      XML_SetCharacterDataHandler(ctx.parser,comps_character_data);
    9.85 -    do
    9.86 +    if (XML_Parse(ctx.parser,contents,length,TRUE)==XML_STATUS_ERROR)
    9.87      {
    9.88 -	XML_GetParsingStatus(ctx.parser,&status);
    9.89 -	switch (status.parsing)
    9.90 -	{
    9.91 -	    case XML_SUSPENDED:
    9.92 -		XML_ResumeParser(ctx.parser);
    9.93 -		break;
    9.94 -	    case XML_PARSING:
    9.95 -	    case XML_INITIALIZED:
    9.96 -		buf=XML_GetBuffer(ctx.parser,XML_BUFFER_SIZE);
    9.97 -		len=g_input_stream_read(G_INPUT_STREAM(stream),buf,
    9.98 -		  XML_BUFFER_SIZE,NULL,NULL);
    9.99 -		if (len<0)
   9.100 -		{
   9.101 -		    comps_group_free(ctx.group);
   9.102 -		    XML_ParserFree(ctx.parser);
   9.103 -		    g_object_unref(stream);
   9.104 -		    return NULL;
   9.105 -		}
   9.106 -		if (!XML_ParseBuffer(ctx.parser,len,!len))
   9.107 -		{
   9.108 -		    comps_group_free(ctx.group);
   9.109 -		    XML_ParserFree(ctx.parser);
   9.110 -		    g_object_unref(stream);
   9.111 -		    return NULL;
   9.112 -		}
   9.113 -		break;
   9.114 -	    case XML_FINISHED:
   9.115 -		break;
   9.116 -	}
   9.117 -    } while (status.parsing!=XML_FINISHED);
   9.118 +	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
   9.119 +	  "%s on line %d of '%s'\n",
   9.120 +	  XML_ErrorString(XML_GetErrorCode(ctx.parser)),
   9.121 +	  XML_GetCurrentLineNumber(ctx.parser),uri);
   9.122 +	XML_ParserFree(ctx.parser);
   9.123 +	razor_uri_free_contents(contents,length);
   9.124 +	return NULL;
   9.125 +    }
   9.126      XML_ParserFree(ctx.parser);
   9.127 -    g_object_unref(stream);
   9.128 +    razor_uri_free_contents(contents,length);
   9.129      comps=plover_comps_new();
   9.130      comps->vendor=ctx.vendor;
   9.131 +    comps->distribution=ctx.distribution;
   9.132 +    comps->database=ctx.database;
   9.133 +    if (comps->database==COMPS_DATABASE_DISTRIBUTION_LOCAL &&
   9.134 +      (!comps->vendor || !comps->distribution))
   9.135 +    {
   9.136 +	g_warning("%s: database setting of distribution-local ignored",uri);
   9.137 +	comps->database=COMPS_DATABASE_GLOBAL;
   9.138 +    }
   9.139      comps->groups=ctx.group;
   9.140      return comps;
   9.141  }
   9.142 @@ -441,7 +436,7 @@
   9.143      file=g_file_new_for_path(filename);
   9.144      uri=g_file_get_uri(file);
   9.145      g_object_unref(file);
   9.146 -    comps=plover_comps_new_from_uri(uri);
   9.147 +    comps=plover_comps_new_from_uri(uri,NULL);
   9.148      g_free(uri);
   9.149      return comps;
   9.150  }
   9.151 @@ -455,3 +450,15 @@
   9.152  	    return group;
   9.153      return NULL;
   9.154  }
   9.155 +
   9.156 +void plover_comps_set_vendor(struct comps *comps,const char *vendor)
   9.157 +{
   9.158 +    free(comps->vendor);
   9.159 +    comps->vendor=strdup(vendor);
   9.160 +}
   9.161 +
   9.162 +void plover_comps_set_distribution(struct comps *comps,const char *distribution)
   9.163 +{
   9.164 +    free(comps->distribution);
   9.165 +    comps->distribution=strdup(distribution);
   9.166 +}
    10.1 --- a/plover/import-yum.c	Fri Jul 08 08:33:44 2016 +0100
    10.2 +++ b/plover/import-yum.c	Sat Jul 16 11:07:18 2016 +0100
    10.3 @@ -1,7 +1,7 @@
    10.4  /*
    10.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
    10.6   * Copyright (C) 2008  Red Hat, Inc
    10.7 - * Copyright (C) 2009, 2011, 2014  J. Ali Harlow <ali@juiblex.co.uk>
    10.8 + * Copyright (C) 2009, 2011, 2014, 2016  J. Ali Harlow <ali@juiblex.co.uk>
    10.9   *
   10.10   * This program is free software; you can redistribute it and/or modify
   10.11   * it under the terms of the GNU General Public License as published by
   10.12 @@ -34,6 +34,7 @@
   10.13  #include <razor.h>
   10.14  #include "plover/plover.h"
   10.15  #include "plover/uri-handler.h"
   10.16 +#include "plover/inputstream.h"
   10.17  
   10.18  /* Import a yum filelist as a razor package set. */
   10.19  
   10.20 @@ -337,7 +338,7 @@
   10.21      void *buf;
   10.22      gssize len;
   10.23      GFile *file;
   10.24 -    GFileInputStream *stream;
   10.25 +    GInputStream *stream;
   10.26      GInputStream *primary,*filelists;
   10.27      GZlibDecompressor *decompressor;
   10.28      XML_ParsingStatus status;
   10.29 @@ -361,10 +362,8 @@
   10.30        yum_filelists_end_element);
   10.31      XML_SetCharacterDataHandler(ctx.filelists_parser,yum_character_data);
   10.32      uri=razor_path_relative_to_uri(base_uri,"repodata/primary.xml.gz",NULL);
   10.33 -    file=g_file_new_for_uri(uri);
   10.34 +    stream=plover_razor_input_stream_new(uri,error);
   10.35      free(uri);
   10.36 -    stream=g_file_read(file,NULL,error);
   10.37 -    g_object_unref(file);
   10.38      if (!stream) {
   10.39  	XML_ParserFree(ctx.primary_parser);
   10.40  	XML_ParserFree(ctx.filelists_parser);
   10.41 @@ -376,11 +375,10 @@
   10.42      g_object_unref(stream);
   10.43      g_object_unref(decompressor);
   10.44      uri=razor_path_relative_to_uri(base_uri,"repodata/filelists.xml.gz",NULL);
   10.45 -    file=g_file_new_for_uri(uri);
   10.46 +    stream=plover_razor_input_stream_new(uri,error);
   10.47      free(uri);
   10.48 -    stream=g_file_read(file,NULL,error);
   10.49 -    g_object_unref(file);
   10.50      if (!stream) {
   10.51 +	g_object_unref(primary);
   10.52  	XML_ParserFree(ctx.primary_parser);
   10.53  	XML_ParserFree(ctx.filelists_parser);
   10.54  	return NULL;
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/plover/inputstream.c	Sat Jul 16 11:07:18 2016 +0100
    11.3 @@ -0,0 +1,303 @@
    11.4 +/*
    11.5 + * Copyright (C) 2006-2007  Red Hat, Inc
    11.6 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    11.7 + *
    11.8 + * This program is free software; you can redistribute it and/or modify
    11.9 + * it under the terms of the GNU General Public License as published by
   11.10 + * the Free Software Foundation; either version 2 of the License, or
   11.11 + * (at your option) any later version.
   11.12 + *
   11.13 + * This program is distributed in the hope that it will be useful,
   11.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 + * GNU General Public License for more details.
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License along
   11.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
   11.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + */
   11.22 +
   11.23 +#include <stdlib.h>
   11.24 +#include <razor.h>
   11.25 +#include <glib.h>
   11.26 +#include <glib/gi18n.h>
   11.27 +#include "plover/inputstream.h"
   11.28 +
   11.29 +/**
   11.30 + * SECTION:ploverrazorinputstream
   11.31 + * @short_description: Streaming input operations on razor files
   11.32 + * @include: plover/inputstream.h
   11.33 + * @see_also: #GMemoryInputStream
   11.34 + *
   11.35 + * #PloverRazorInputStream provides input streams that get their
   11.36 + * content via razor's URI input routines.
   11.37 + */
   11.38 +
   11.39 +struct _PloverRazorInputStreamPrivate
   11.40 +{
   11.41 +    void *buf;
   11.42 +    gsize len;
   11.43 +    gsize pos;
   11.44 +};
   11.45 +
   11.46 +static gssize plover_razor_input_stream_read(GInputStream *stream,void *buffer,
   11.47 +  gsize count,GCancellable *cancellable,GError **error);
   11.48 +static gssize plover_razor_input_stream_skip(GInputStream *stream,gsize count,
   11.49 +  GCancellable *cancellable,GError **error);
   11.50 +static gboolean plover_razor_input_stream_close(GInputStream *stream,
   11.51 +  GCancellable *cancellable,GError **error);
   11.52 +static void plover_razor_input_stream_skip_async(GInputStream *stream,
   11.53 +  gsize count,int io_priority,GCancellable *cancellable,
   11.54 +  GAsyncReadyCallback callback,gpointer data);
   11.55 +static gssize plover_razor_input_stream_skip_finish(GInputStream *stream,
   11.56 +  GAsyncResult *result,GError **error);
   11.57 +static void plover_razor_input_stream_close_async(GInputStream *stream,
   11.58 +  int io_priority,GCancellable *cancellable,GAsyncReadyCallback callback,
   11.59 +  gpointer data);
   11.60 +static gboolean plover_razor_input_stream_close_finish(GInputStream *stream,
   11.61 +  GAsyncResult *result,GError **error);
   11.62 +static void
   11.63 +  plover_razor_input_stream_seekable_iface_init(GSeekableIface *iface);
   11.64 +static goffset plover_razor_input_stream_tell(GSeekable *seekable);
   11.65 +static gboolean plover_razor_input_stream_can_seek(GSeekable *seekable);
   11.66 +static gboolean plover_razor_input_stream_seek(GSeekable *seekable,
   11.67 +  goffset offset,GSeekType type,GCancellable *cancellable,GError **error);
   11.68 +static gboolean plover_razor_input_stream_can_truncate(GSeekable *seekable);
   11.69 +static gboolean plover_razor_input_stream_truncate(GSeekable *seekable,
   11.70 +  goffset offset,GCancellable *cancellable,GError **error);
   11.71 +static void plover_razor_input_stream_pollable_iface_init(
   11.72 +  GPollableInputStreamInterface *iface);
   11.73 +static gboolean
   11.74 +  plover_razor_input_stream_is_readable(GPollableInputStream *stream);
   11.75 +static GSource *
   11.76 +  plover_razor_input_stream_create_source(GPollableInputStream *stream,
   11.77 +  GCancellable *cancellable);
   11.78 +static void plover_razor_input_stream_finalize(GObject *object);
   11.79 +
   11.80 +G_DEFINE_TYPE_WITH_CODE(PloverRazorInputStream,plover_razor_input_stream,
   11.81 +  G_TYPE_INPUT_STREAM,
   11.82 +  G_IMPLEMENT_INTERFACE(G_TYPE_SEEKABLE,
   11.83 +    plover_razor_input_stream_seekable_iface_init);
   11.84 +  G_IMPLEMENT_INTERFACE(G_TYPE_POLLABLE_INPUT_STREAM,
   11.85 +    plover_razor_input_stream_pollable_iface_init);
   11.86 +)
   11.87 +
   11.88 +static void
   11.89 +  plover_razor_input_stream_class_init(PloverRazorInputStreamClass *klass)
   11.90 +{
   11.91 +    GObjectClass *object_class;
   11.92 +    GInputStreamClass *istream_class;
   11.93 +    g_type_class_add_private(klass,sizeof(PloverRazorInputStreamPrivate));
   11.94 +    object_class=G_OBJECT_CLASS(klass);
   11.95 +    object_class->finalize=plover_razor_input_stream_finalize;
   11.96 +    istream_class=G_INPUT_STREAM_CLASS(klass);
   11.97 +    istream_class->read_fn=plover_razor_input_stream_read;
   11.98 +    istream_class->skip=plover_razor_input_stream_skip;
   11.99 +    istream_class->close_fn=plover_razor_input_stream_close;
  11.100 +    istream_class->skip_async=plover_razor_input_stream_skip_async;
  11.101 +    istream_class->skip_finish=plover_razor_input_stream_skip_finish;
  11.102 +    istream_class->close_async=plover_razor_input_stream_close_async;
  11.103 +    istream_class->close_finish=plover_razor_input_stream_close_finish;
  11.104 +}
  11.105 +
  11.106 +static void plover_razor_input_stream_finalize(GObject *object)
  11.107 +{
  11.108 +    PloverRazorInputStream *razor_stream;
  11.109 +    PloverRazorInputStreamPrivate *priv;
  11.110 +    razor_stream=PLOVER_RAZOR_INPUT_STREAM(object);
  11.111 +    priv=razor_stream->priv;
  11.112 +    razor_uri_free_contents(priv->buf,priv->len);
  11.113 +    G_OBJECT_CLASS(plover_razor_input_stream_parent_class)->finalize(object);
  11.114 +}
  11.115 +
  11.116 +static void plover_razor_input_stream_seekable_iface_init(GSeekableIface *iface)
  11.117 +{
  11.118 +    iface->tell=plover_razor_input_stream_tell;
  11.119 +    iface->can_seek=plover_razor_input_stream_can_seek;
  11.120 +    iface->seek=plover_razor_input_stream_seek;
  11.121 +    iface->can_truncate=plover_razor_input_stream_can_truncate;
  11.122 +    iface->truncate_fn=plover_razor_input_stream_truncate;
  11.123 +}
  11.124 +
  11.125 +static void plover_razor_input_stream_pollable_iface_init(
  11.126 +  GPollableInputStreamInterface *iface)
  11.127 +{
  11.128 +    iface->is_readable=plover_razor_input_stream_is_readable;
  11.129 +    iface->create_source=plover_razor_input_stream_create_source;
  11.130 +}
  11.131 +
  11.132 +static void plover_razor_input_stream_init(PloverRazorInputStream *stream)
  11.133 +{
  11.134 +    stream->priv=G_TYPE_INSTANCE_GET_PRIVATE(stream,
  11.135 +      PLOVER_TYPE_RAZOR_INPUT_STREAM,PloverRazorInputStreamPrivate);
  11.136 +}
  11.137 +
  11.138 +GInputStream *plover_razor_input_stream_new(const char *uri,GError **error)
  11.139 +{
  11.140 +    void *buf;
  11.141 +    size_t len;
  11.142 +    struct razor_error *tmp_error=NULL;
  11.143 +    GInputStream *stream;
  11.144 +    PloverRazorInputStreamPrivate *priv;
  11.145 +    g_return_if_fail(uri!=NULL);
  11.146 +    buf=razor_uri_get_contents(uri,&len,FALSE,&tmp_error);
  11.147 +    if (!buf)
  11.148 +    {
  11.149 +	plover_propagate_razor_error(error,tmp_error);
  11.150 +	return NULL;
  11.151 +    }
  11.152 +    stream=g_object_new(PLOVER_TYPE_RAZOR_INPUT_STREAM,NULL);
  11.153 +    priv=PLOVER_RAZOR_INPUT_STREAM(stream)->priv;
  11.154 +    priv->buf=buf;
  11.155 +    priv->len=len;
  11.156 +    return stream;
  11.157 +}
  11.158 +
  11.159 +static gssize plover_razor_input_stream_read(GInputStream *stream,void *buffer,
  11.160 +  gsize count,GCancellable *cancellable,GError **error)
  11.161 +{
  11.162 +    PloverRazorInputStream *razor_stream;
  11.163 +    PloverRazorInputStreamPrivate *priv;
  11.164 +    razor_stream=PLOVER_RAZOR_INPUT_STREAM(stream);
  11.165 +    priv=razor_stream->priv;
  11.166 +    count=MIN(count,priv->len-priv->pos);
  11.167 +    memcpy(buffer,(guint8 *)priv->buf+priv->pos,count);
  11.168 +    priv->pos+=count;
  11.169 +    return count;
  11.170 +}
  11.171 +
  11.172 +static gssize plover_razor_input_stream_skip(GInputStream *stream,gsize count,
  11.173 +  GCancellable *cancellable,GError **error)
  11.174 +{
  11.175 +    PloverRazorInputStream *razor_stream;
  11.176 +    PloverRazorInputStreamPrivate *priv;
  11.177 +    razor_stream=PLOVER_RAZOR_INPUT_STREAM(stream);
  11.178 +    priv=razor_stream->priv;
  11.179 +    count=MIN(count,priv->len-priv->pos);
  11.180 +    priv->pos+=count;
  11.181 +    return count;
  11.182 +}
  11.183 +
  11.184 +static gboolean plover_razor_input_stream_close(GInputStream *stream,
  11.185 +  GCancellable *cancellable,GError **error)
  11.186 +{
  11.187 +    return TRUE;
  11.188 +}
  11.189 +
  11.190 +static void plover_razor_input_stream_skip_async(GInputStream *stream,
  11.191 +  gsize count,int io_priority,GCancellable *cancellable,
  11.192 +  GAsyncReadyCallback callback,gpointer user_data)
  11.193 +{
  11.194 +    GTask *task;
  11.195 +    gssize nskipped;
  11.196 +    GError *error=NULL;
  11.197 +    nskipped=G_INPUT_STREAM_GET_CLASS(stream)->skip(stream,count,cancellable,
  11.198 +      &error);
  11.199 +    task=g_task_new(stream,cancellable,callback,user_data);
  11.200 +    if (error)
  11.201 +	g_task_return_error(task,error);
  11.202 +    else
  11.203 +	g_task_return_int(task,nskipped);
  11.204 +    g_object_unref(task);
  11.205 +}
  11.206 +
  11.207 +static gssize plover_razor_input_stream_skip_finish(GInputStream *stream,
  11.208 +  GAsyncResult *result,GError **error)
  11.209 +{
  11.210 +    g_return_val_if_fail(g_task_is_valid(result,stream),-1);
  11.211 +    return g_task_propagate_int(G_TASK(result),error);
  11.212 +}
  11.213 +
  11.214 +static void plover_razor_input_stream_close_async(GInputStream *stream,
  11.215 +  int io_priority,GCancellable *cancellable,GAsyncReadyCallback callback,
  11.216 +  gpointer user_data)
  11.217 +{
  11.218 +    GTask *task;
  11.219 +    task=g_task_new(stream,cancellable,callback,user_data);
  11.220 +    g_task_return_boolean(task,TRUE);
  11.221 +    g_object_unref (task);
  11.222 +}
  11.223 +
  11.224 +static gboolean plover_razor_input_stream_close_finish(GInputStream *stream,
  11.225 +  GAsyncResult *result,GError **error)
  11.226 +{
  11.227 +    return TRUE;
  11.228 +}
  11.229 +
  11.230 +static goffset plover_razor_input_stream_tell(GSeekable *seekable)
  11.231 +{
  11.232 +    PloverRazorInputStream *razor_stream;
  11.233 +    PloverRazorInputStreamPrivate *priv;
  11.234 +    razor_stream=PLOVER_RAZOR_INPUT_STREAM(seekable);
  11.235 +    priv=razor_stream->priv;
  11.236 +    return priv->pos;
  11.237 +}
  11.238 +
  11.239 +static gboolean plover_razor_input_stream_can_seek(GSeekable *seekable)
  11.240 +{
  11.241 +    return TRUE;
  11.242 +}
  11.243 +
  11.244 +static gboolean plover_razor_input_stream_seek(GSeekable *seekable,
  11.245 +  goffset offset,GSeekType type,GCancellable *cancellable,GError **error)
  11.246 +{
  11.247 +    PloverRazorInputStream *razor_stream;
  11.248 +    PloverRazorInputStreamPrivate *priv;
  11.249 +    goffset absolute;
  11.250 +    razor_stream=PLOVER_RAZOR_INPUT_STREAM(seekable);
  11.251 +    priv=razor_stream->priv;
  11.252 +    switch(type)
  11.253 +    {
  11.254 +	case G_SEEK_CUR:
  11.255 +	    absolute=priv->pos+offset;
  11.256 +	    break;
  11.257 +	case G_SEEK_SET:
  11.258 +	    absolute=offset;
  11.259 +	    break;
  11.260 +	case G_SEEK_END:
  11.261 +	    absolute=priv->len+offset;
  11.262 +	    break;
  11.263 +	default:
  11.264 +	    g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_INVALID_ARGUMENT,
  11.265 +	      _("Invalid GSeekType supplied"));
  11.266 +	    return FALSE;
  11.267 +    }
  11.268 +    if (absolute<0 || absolute>priv->len)
  11.269 +    {
  11.270 +	g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_INVALID_ARGUMENT,
  11.271 +	  _("Invalid seek request"));
  11.272 +	return FALSE;
  11.273 +    }
  11.274 +    priv->pos=absolute;
  11.275 +    return TRUE;
  11.276 +}
  11.277 +
  11.278 +static gboolean plover_razor_input_stream_can_truncate(GSeekable *seekable)
  11.279 +{
  11.280 +    return FALSE;
  11.281 +}
  11.282 +
  11.283 +static gboolean plover_razor_input_stream_truncate(GSeekable *seekable,
  11.284 +  goffset offset,GCancellable *cancellable,GError **error)
  11.285 +{
  11.286 +    g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_NOT_SUPPORTED,
  11.287 +      _("Cannot truncate PloverRazorInputStream"));
  11.288 +    return FALSE;
  11.289 +}
  11.290 +
  11.291 +static gboolean
  11.292 +  plover_razor_input_stream_is_readable(GPollableInputStream *stream)
  11.293 +{
  11.294 +    return TRUE;
  11.295 +}
  11.296 +
  11.297 +static GSource *
  11.298 +  plover_razor_input_stream_create_source(GPollableInputStream *stream,
  11.299 +  GCancellable *cancellable)
  11.300 +{
  11.301 +    GSource *base_source,*pollable_source;
  11.302 +    base_source=g_timeout_source_new(0);
  11.303 +    pollable_source=g_pollable_source_new_full(stream,base_source,cancellable);
  11.304 +    g_source_unref(base_source);
  11.305 +    return pollable_source;
  11.306 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/plover/inputstream.h	Sat Jul 16 11:07:18 2016 +0100
    12.3 @@ -0,0 +1,70 @@
    12.4 +/*
    12.5 + * Copyright (C) 2006-2007  Red Hat, Inc
    12.6 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    12.7 + *
    12.8 + * This program is free software; you can redistribute it and/or modify
    12.9 + * it under the terms of the GNU General Public License as published by
   12.10 + * the Free Software Foundation; either version 2 of the License, or
   12.11 + * (at your option) any later version.
   12.12 + *
   12.13 + * This program is distributed in the hope that it will be useful,
   12.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.16 + * GNU General Public License for more details.
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License along
   12.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
   12.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + */
   12.22 +
   12.23 +#ifndef __PLOVER_INPUT_STREAM_H__
   12.24 +#define __PLOVER_INPUT_STREAM_H__
   12.25 +
   12.26 +#include <gio/gio.h>
   12.27 +
   12.28 +G_BEGIN_DECLS
   12.29 +
   12.30 +#define PLOVER_TYPE_RAZOR_INPUT_STREAM	plover_razor_input_stream_get_type()
   12.31 +#define PLOVER_RAZOR_INPUT_STREAM(o)	G_TYPE_CHECK_INSTANCE_CAST(o, \
   12.32 +					  PLOVER_TYPE_RAZOR_INPUT_STREAM, \
   12.33 +					  PloverRazorInputStream)
   12.34 +#define PLOVER_RAZOR_INPUT_STREAM_CLASS(k) \
   12.35 +					G_TYPE_CHECK_CLASS_CAST(k, \
   12.36 +					  PLOVER_TYPE_RAZOR_INPUT_STREAM, \
   12.37 +					  PloverRazorInputStreamClass))
   12.38 +#define PLOVER_IS_RAZOR_INPUT_STREAM(o)	G_TYPE_CHECK_INSTANCE_TYPE(o, \
   12.39 +					  PLOVER_TYPE_RAZOR_INPUT_STREAM)
   12.40 +#define PLOVER_IS_RAZOR_INPUT_STREAM_CLASS(k) \
   12.41 +					G_TYPE_CHECK_CLASS_TYPE(k, \
   12.42 +					  PLOVER_TYPE_RAZOR_INPUT_STREAM)
   12.43 +#define PLOVER_RAZOR_INPUT_STREAM_GET_CLASS(o) \
   12.44 +					G_TYPE_INSTANCE_GET_CLASS(o, \
   12.45 +					  PLOVER_TYPE_RAZOR_INPUT_STREAM, \
   12.46 +					  PloverRazorInputStreamClass)
   12.47 +
   12.48 +/**
   12.49 + * PloverRazorInputStream:
   12.50 + *
   12.51 + * Implements #GInputStream for razor URI routines.
   12.52 + */
   12.53 +typedef struct _PloverRazorInputStream PloverRazorInputStream;
   12.54 +typedef struct _PloverRazorInputStreamClass PloverRazorInputStreamClass;
   12.55 +typedef struct _PloverRazorInputStreamPrivate PloverRazorInputStreamPrivate;
   12.56 +
   12.57 +struct _PloverRazorInputStream
   12.58 +{
   12.59 +    GInputStream parent_instance;
   12.60 +    PloverRazorInputStreamPrivate *priv;
   12.61 +};
   12.62 +
   12.63 +struct _PloverRazorInputStreamClass
   12.64 +{
   12.65 +    GInputStreamClass parent_class;
   12.66 +};
   12.67 +
   12.68 +GType plover_razor_input_stream_get_type(void) G_GNUC_CONST;
   12.69 +GInputStream *plover_razor_input_stream_new(const char *uri,GError **error);
   12.70 +
   12.71 +G_END_DECLS
   12.72 +
   12.73 +#endif /* _PLOVER_INPUT_STREAM_H__ */
    13.1 --- a/plover/packageset.c	Fri Jul 08 08:33:44 2016 +0100
    13.2 +++ b/plover/packageset.c	Sat Jul 16 11:07:18 2016 +0100
    13.3 @@ -32,7 +32,7 @@
    13.4  G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT);
    13.5  
    13.6  typedef struct _PloverPackageSetPrivate {
    13.7 -    gchar *install_root;
    13.8 +    gchar *root_uri;
    13.9      struct razor_root *root;
   13.10      struct razor_set *set;
   13.11      GSList *packages;
   13.12 @@ -56,7 +56,7 @@
   13.13  {
   13.14      PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
   13.15      g_free(priv->guessed_prefix);
   13.16 -    g_free(priv->install_root);
   13.17 +    g_free(priv->root_uri);
   13.18      G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj);
   13.19  }
   13.20  
   13.21 @@ -76,8 +76,8 @@
   13.22      }
   13.23      if (priv->root)
   13.24      {
   13.25 -	g_free(priv->install_root);
   13.26 -	priv->install_root=NULL;
   13.27 +	g_free(priv->root_uri);
   13.28 +	priv->root_uri=NULL;
   13.29  	razor_root_close(priv->root);
   13.30  	priv->root=NULL;
   13.31      }
   13.32 @@ -120,25 +120,20 @@
   13.33      }
   13.34  }
   13.35  
   13.36 -gboolean plover_package_set_open(PloverPackageSet *set,const char *install_root,
   13.37 +gboolean plover_package_set_open(PloverPackageSet *set,const char *root_uri,
   13.38    gboolean exclusive,GError **err)
   13.39  {
   13.40      struct razor_root *root=NULL;
   13.41      struct razor_set *system=NULL;
   13.42      PloverPackageSetPrivate *priv;
   13.43      struct razor_error *error=NULL;
   13.44 -    GFile *file;
   13.45 -    gchar *uri;
   13.46      g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
   13.47 -    file=g_file_new_for_path(*install_root?install_root:"/");
   13.48 -    uri=g_file_get_uri(file);
   13.49 -    g_object_unref(file);
   13.50      if (exclusive)
   13.51      {
   13.52 -	root=razor_root_open(uri,NULL);
   13.53 +	root=razor_root_open(root_uri,NULL);
   13.54  	if (!root)
   13.55  	{
   13.56 -	    if (razor_root_create(uri,&error))
   13.57 +	    if (razor_root_create(root_uri,&error))
   13.58  	    {
   13.59  		if (razor_error_get_domain(error)==RAZOR_GENERAL_ERROR &&
   13.60  		  razor_error_get_code(error)==
   13.61 @@ -146,15 +141,14 @@
   13.62  		{
   13.63  		    razor_error_free(error);
   13.64  		    error=NULL;
   13.65 -		    root=razor_root_open(uri,&error);
   13.66 +		    root=razor_root_open(root_uri,&error);
   13.67  		}                             
   13.68  	    }
   13.69  	    else
   13.70 -		root=razor_root_open(uri,&error);
   13.71 +		root=razor_root_open(root_uri,&error);
   13.72  	    if (!root)                        
   13.73  	    {
   13.74  		plover_propagate_razor_error(err,error);
   13.75 -		g_free(uri);
   13.76  		return FALSE;
   13.77  	    }
   13.78  	}
   13.79 @@ -163,8 +157,7 @@
   13.80  	    razor_set_ref(system);
   13.81      }
   13.82      else
   13.83 -	system=razor_root_open_read_only(uri,&error);
   13.84 -    g_free(uri);
   13.85 +	system=razor_root_open_read_only(root_uri,&error);
   13.86      if (error)
   13.87      {
   13.88  	g_set_error_literal(err,PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED,
   13.89 @@ -183,8 +176,8 @@
   13.90  	razor_root_close(priv->root);
   13.91  	priv->root=NULL;
   13.92      }
   13.93 -    g_free(priv->install_root);
   13.94 -    priv->install_root=g_strdup(install_root);
   13.95 +    g_free(priv->root_uri);
   13.96 +    priv->root_uri=g_strdup(root_uri);
   13.97      priv->root=root;
   13.98      priv->set=system;
   13.99      return TRUE;
  13.100 @@ -195,7 +188,7 @@
  13.101      PloverPackageSetPrivate *priv;
  13.102      g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
  13.103      priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
  13.104 -    return priv->install_root;
  13.105 +    return priv->root_uri;
  13.106  }
  13.107  
  13.108  gboolean plover_package_set_get_exclusive(PloverPackageSet *set)
  13.109 @@ -634,7 +627,7 @@
  13.110      struct razor_file_iterator *fi;
  13.111      GSList *packages,*lnk;
  13.112      PloverPackage *package;
  13.113 -    default_prefix=plover_default_prefix_for_vendor("");
  13.114 +    default_prefix=plover_comps_get_default_prefix(NULL);
  13.115      if (!default_prefix)
  13.116  	return;
  13.117      len=strlen(default_prefix);
  13.118 @@ -665,6 +658,7 @@
  13.119  {
  13.120      GArray *popchart;
  13.121      const char *prefix;
  13.122 +    struct comps *comps;
  13.123      PloverPackageSetPrivate *priv;
  13.124      g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
  13.125      priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
  13.126 @@ -685,7 +679,56 @@
  13.127  	plover_package_set_popchart_free(popchart);
  13.128      }
  13.129      if (!priv->guessed_prefix)
  13.130 -	priv->guessed_prefix=
  13.131 -	  plover_default_prefix_for_vendor("Acme Corporation");
  13.132 +    {
  13.133 +	comps=plover_comps_new();
  13.134 +	plover_comps_set_vendor(comps,"Acme Corporation");
  13.135 +	priv->guessed_prefix=plover_comps_get_default_prefix(comps);
  13.136 +	plover_comps_free(comps);
  13.137 +    }
  13.138      return priv->guessed_prefix;
  13.139  }
  13.140 +
  13.141 +/*
  13.142 + * Returns:
  13.143 + *	 0 if there are any files that don't match prefix, or
  13.144 + *	-1 if there are no files at all, or
  13.145 + * 	 1 if there are files and they all match prefix.
  13.146 + */
  13.147 +
  13.148 +int plover_package_set_files_match_prefix(PloverPackageSet *set,
  13.149 +  const char *prefix)
  13.150 +{
  13.151 +    int len,matches=-1;
  13.152 +    const char *name;
  13.153 +    const char *install_root;
  13.154 +    struct razor_package *package;
  13.155 +    struct razor_package_iterator *pi;
  13.156 +    struct razor_file_iterator *fi;
  13.157 +    PloverPackageSetPrivate *priv;
  13.158 +    g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),-1);
  13.159 +    priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
  13.160 +    len=strlen(prefix);
  13.161 +    while(len && prefix[len-1]=='/')
  13.162 +	len--;
  13.163 +    if (priv->set)
  13.164 +    {
  13.165 +	pi=razor_package_iterator_create(priv->set);
  13.166 +	while (matches &&
  13.167 +	  razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
  13.168 +	{
  13.169 +	    fi=razor_file_iterator_create(priv->set,package,0);
  13.170 +	    while (matches && razor_file_iterator_next(fi,&name))
  13.171 +	    {
  13.172 +		g_message("plover_package_set_files_match_prefix(%s): %s",prefix,name);
  13.173 +		if (strncmp(name,prefix,len) ||
  13.174 +		  name[len]!='\0' && name[len]!='/')
  13.175 +		    matches=0;
  13.176 +		else
  13.177 +		    matches=1;
  13.178 +	    }
  13.179 +	    razor_file_iterator_destroy(fi);
  13.180 +	}
  13.181 +	razor_package_iterator_destroy(pi);
  13.182 +    }
  13.183 +    return matches;
  13.184 +}
    14.1 --- a/plover/packageset.h	Fri Jul 08 08:33:44 2016 +0100
    14.2 +++ b/plover/packageset.h	Sat Jul 16 11:07:18 2016 +0100
    14.3 @@ -67,6 +67,8 @@
    14.4  gboolean plover_package_set_get_no_details(PloverPackageSet *set);
    14.5  const char *plover_package_set_guess_prefix(PloverPackageSet *set,
    14.6    GError **error);
    14.7 +int plover_package_set_files_match_prefix(PloverPackageSet *set,
    14.8 +  const char *prefix);
    14.9  
   14.10  G_END_DECLS
   14.11  
    15.1 --- a/plover/plover.h	Fri Jul 08 08:33:44 2016 +0100
    15.2 +++ b/plover/plover.h	Sat Jul 16 11:07:18 2016 +0100
    15.3 @@ -49,10 +49,18 @@
    15.4      struct comps_requirement *packages;
    15.5  };
    15.6  
    15.7 +enum comps_database_setting
    15.8 +{
    15.9 +    COMPS_DATABASE_GLOBAL = 0,		/* Default value */
   15.10 +    COMPS_DATABASE_DISTRIBUTION_LOCAL,
   15.11 +};
   15.12 +
   15.13  struct comps
   15.14  {
   15.15      char *vendor;
   15.16      struct comps_group *groups;
   15.17 +    char *distribution;
   15.18 +    enum comps_database_setting database;
   15.19  };
   15.20  
   15.21  struct plover_vector
   15.22 @@ -61,10 +69,10 @@
   15.23      char **strings;
   15.24  };
   15.25  
   15.26 -gchar *plover_default_prefix_for_vendor(const char *vendor);
   15.27  gchar *plover_pre_install_prefix(void);
   15.28  void plover_purge_reports(const char *path);
   15.29  gchar *plover_get_reports_directory(void);
   15.30 +char *plover_get_program(const char *argv0);
   15.31  char *plover_get_program_directory(const char *argv0);
   15.32  GQuark plover_razor_error_quark(void);
   15.33  GQuark plover_posix_error_quark(void);
   15.34 @@ -92,11 +100,13 @@
   15.35  int plover_installed_files_match_prefix(const char *prefix);
   15.36  
   15.37  struct comps *plover_comps_new(void);
   15.38 -struct comps *plover_comps_new_from_uri(const char *uri);
   15.39 +struct comps *plover_comps_new_from_uri(const char *uri,GError **error);
   15.40  struct comps *plover_comps_new_from_file(const char *filename);
   15.41  void plover_comps_free(struct comps *comps);
   15.42  struct comps_group *plover_comps_lookup_group(struct comps *comps,
   15.43    const char *id);
   15.44 +void plover_comps_set_vendor(struct comps *comps,const char *vendor);
   15.45 +gchar *plover_comps_get_default_prefix(struct comps *comps);
   15.46  
   15.47  int plover_log_open(const char *path);
   15.48  void plover_exception_handler_init(void);
    16.1 --- a/plover/razor.c	Fri Jul 08 08:33:44 2016 +0100
    16.2 +++ b/plover/razor.c	Sat Jul 16 11:07:18 2016 +0100
    16.3 @@ -18,6 +18,7 @@
    16.4   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    16.5   */
    16.6  
    16.7 +#define _GNU_SOURCE
    16.8  #include <stdlib.h>
    16.9  #include <stdio.h>
   16.10  #include <stdarg.h>
   16.11 @@ -48,7 +49,7 @@
   16.12   * is met (in which case the action is consumed).
   16.13   */
   16.14  int plover_run_transaction(struct razor_transaction *trans,
   16.15 -  struct razor_install_iterator *ii,const char *install_root,
   16.16 +  struct razor_install_iterator *ii,const char *root_uri,
   16.17    struct razor_set *system,PloverPackageSet *next,PloverRepository *upstream,
   16.18    struct razor_atomic *atomic,struct razor_relocations *relocations,
   16.19    enum razor_stage_type stage,GCancellable *cancellable)
   16.20 @@ -62,12 +63,9 @@
   16.21      int r,count;
   16.22      GError *tmp_error=NULL;
   16.23      PloverPackage *package;
   16.24 -    GFile *file;
   16.25 -    gchar *uri;
   16.26      plover__uri_handler_init();
   16.27 -    file=g_file_new_for_path(*install_root?install_root:"/");
   16.28 -    uri=g_file_get_uri(file);
   16.29 -    g_object_unref(file);
   16.30 +    if (!*root_uri)
   16.31 +	root_uri="file:/";
   16.32      switch(stage)
   16.33      {
   16.34  	case RAZOR_STAGE_SCRIPTS_PRE:
   16.35 @@ -89,7 +87,6 @@
   16.36  	{
   16.37  	    razor_atomic_abort(atomic,PLOVER_GENERAL_ERROR,
   16.38  	      PLOVER_GENERAL_ERROR_CANCELLED,"Operation was cancelled");
   16.39 -	    g_free(uri);
   16.40  	    return -1;
   16.41  	}
   16.42  	if (action==RAZOR_INSTALL_ACTION_REMOVE)
   16.43 @@ -99,7 +96,7 @@
   16.44  	    if (stage==RAZOR_STAGE_FILES)
   16.45  		printf("  Removing : %s ",name);
   16.46  	    r=razor_package_remove(system,plover_package_set_get_razor(next),
   16.47 -	      atomic,pkg,uri,count,stage);
   16.48 +	      atomic,pkg,root_uri,count,stage);
   16.49  	    if (stage==RAZOR_STAGE_FILES)
   16.50  		printf("\n");
   16.51  	}
   16.52 @@ -111,7 +108,6 @@
   16.53  	    {
   16.54  		plover_propagate_g_error(&error,tmp_error);
   16.55  		razor_atomic_propagate_error(atomic,error,NULL);
   16.56 -		g_free(uri);
   16.57  		return -1;
   16.58  	    }
   16.59  	    if (stage==RAZOR_STAGE_FILES)
   16.60 @@ -119,22 +115,17 @@
   16.61  	    if (relocations)
   16.62  		razor_rpm_set_relocations(rpm,relocations);
   16.63  	    razor_transaction_fixup_package(trans,pkg,rpm);
   16.64 -	    r=razor_rpm_install(rpm,atomic,uri,1,stage);
   16.65 +	    r=razor_rpm_install(rpm,atomic,root_uri,1,stage);
   16.66  	    razor_rpm_close(rpm);
   16.67  	    if (stage==RAZOR_STAGE_FILES)
   16.68  		printf("\n");
   16.69  	}
   16.70 -	else if (action==RAZOR_INSTALL_ACTION_COMMIT) {
   16.71 -	    g_free(uri);
   16.72 +	else if (action==RAZOR_INSTALL_ACTION_COMMIT)
   16.73  	    return 1;
   16.74 -	}
   16.75  	else
   16.76  	    r=0;
   16.77  	if (razor_atomic_in_error_state(atomic))
   16.78 -	{
   16.79 -	    g_free(uri);
   16.80  	    return -1;
   16.81 -	}
   16.82  	else if (r)
   16.83  	{
   16.84  	    if (action==RAZOR_INSTALL_ACTION_REMOVE)
   16.85 @@ -164,7 +155,6 @@
   16.86  		fprintf(stderr,"error: %s, exit status %d\n",t,r);
   16.87  		razor_atomic_abort(atomic,PLOVER_SCRIPTLET_ERROR,r,t);
   16.88  		g_free(t);
   16.89 -		g_free(uri);
   16.90  		return -1;
   16.91  	    }
   16.92  	    else
   16.93 @@ -174,7 +164,6 @@
   16.94  		  name,version,arch,r);
   16.95  	}
   16.96      }
   16.97 -    g_free(uri);
   16.98      return 0;
   16.99  }
  16.100  
  16.101 @@ -209,23 +198,12 @@
  16.102    GError **error)
  16.103  {
  16.104      gboolean retval;
  16.105 -    GError *tmp_error=NULL;
  16.106      PloverTransaction *transaction;
  16.107 -    transaction=plover_transaction_new_update_uri(base_uri,prefix,pkgs,
  16.108 -      &tmp_error);
  16.109 +    transaction=plover_transaction_new_update_uri(base_uri,prefix,pkgs,error);
  16.110      if (!transaction)
  16.111 -    {
  16.112 -	retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT);
  16.113 -	if (retval)
  16.114 -	    g_error_free(tmp_error);
  16.115 -	else
  16.116 -	    g_propagate_error(error,tmp_error);
  16.117 -    }
  16.118 -    else
  16.119 -    {
  16.120 -	retval=plover_transaction_commit(transaction,NULL,error);
  16.121 -	g_object_unref(transaction);
  16.122 -    }
  16.123 +	return FALSE;
  16.124 +    retval=plover_transaction_commit(transaction,NULL,error);
  16.125 +    g_object_unref(transaction);
  16.126      return retval;
  16.127  }
  16.128  
  16.129 @@ -233,22 +211,12 @@
  16.130    GError **error)
  16.131  {
  16.132      gboolean retval;
  16.133 -    GError *tmp_error=NULL;
  16.134      PloverTransaction *transaction;
  16.135 -    transaction=plover_transaction_new_update(base,prefix,pkgs,&tmp_error);
  16.136 +    transaction=plover_transaction_new_update(base,prefix,pkgs,error);
  16.137      if (!transaction)
  16.138 -    {
  16.139 -	retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT);
  16.140 -	if (retval)
  16.141 -	    g_error_free(tmp_error);
  16.142 -	else
  16.143 -	    g_propagate_error(error,tmp_error);
  16.144 -    }
  16.145 -    else
  16.146 -    {
  16.147 -	retval=plover_transaction_commit(transaction,NULL,error);
  16.148 -	g_object_unref(transaction);
  16.149 -    }
  16.150 +	return FALSE;
  16.151 +    retval=plover_transaction_commit(transaction,NULL,error);
  16.152 +    g_object_unref(transaction);
  16.153      return retval;
  16.154  }
  16.155  
  16.156 @@ -284,12 +252,15 @@
  16.157  }
  16.158  
  16.159  /*
  16.160 - * Note: If there are no installed files, then any prefix will match.
  16.161 + * Returns:
  16.162 + *	 0 if there are any installed files that don't match prefix, or
  16.163 + *	-1 if there are no installed files at all, or
  16.164 + * 	 1 if there are installed files and they all match prefix.
  16.165   */
  16.166  
  16.167  int plover_installed_files_match_prefix(const char *prefix)
  16.168  {
  16.169 -    int len,matches=1;
  16.170 +    int len,matches=-1;
  16.171      const char *name;
  16.172      const char *install_root;
  16.173      struct razor_set *set;
  16.174 @@ -316,6 +287,8 @@
  16.175  		if (strncmp(name,prefix,len) ||
  16.176  		  name[len]!='\0' && name[len]!='/')
  16.177  		    matches=0;
  16.178 +		else
  16.179 +		    matches=1;
  16.180  	    }
  16.181  	    razor_file_iterator_destroy(fi);
  16.182  	}
  16.183 @@ -324,3 +297,204 @@
  16.184      }
  16.185      return matches;
  16.186  }
  16.187 +
  16.188 +#include <fcntl.h>
  16.189 +#include <dlfcn.h>
  16.190 +
  16.191 +struct razor_set_counter
  16.192 +{
  16.193 +    struct razor_set *set;
  16.194 +    int count;
  16.195 +};
  16.196 +
  16.197 +static GList *counters;
  16.198 +
  16.199 +static struct razor_set_counter *get_razor_set_counter(struct razor_set *set)
  16.200 +{
  16.201 +    GList *lnk;
  16.202 +    struct razor_set_counter *counter;
  16.203 +    for(lnk=counters;lnk;lnk=lnk->next)
  16.204 +    {
  16.205 +	counter=lnk->data;
  16.206 +	if (counter->set==set)
  16.207 +	    return counter;
  16.208 +    }
  16.209 +    counter=g_new(struct razor_set_counter,1);
  16.210 +    counter->set=set;
  16.211 +    counter->count=0;
  16.212 +    counters=g_list_prepend(counters,counter);
  16.213 +    return counter;
  16.214 +}
  16.215 +
  16.216 +static void dump_razor_set_ref(struct razor_set *set)
  16.217 +{
  16.218 +    FILE *fp;
  16.219 +    gchar *filename;
  16.220 +    void *bt[16];
  16.221 +    size_t len;
  16.222 +    struct razor_set_counter *counter;
  16.223 +    filename=g_strdup_printf("razor-set-%p",set);
  16.224 +    fp=fopen(filename,"a");
  16.225 +    g_free(filename);
  16.226 +    counter=get_razor_set_counter(set);
  16.227 +    counter->count++;
  16.228 +    fprintf(fp,"Ref %p (%d refs)\n",set,counter->count);
  16.229 +    fflush(fp);
  16.230 +    len=backtrace(bt,G_N_ELEMENTS(bt));
  16.231 +    backtrace_symbols_fd(bt,len,fileno(fp));
  16.232 +    fprintf(fp,"\n");
  16.233 +    fclose(fp);
  16.234 +}
  16.235 +
  16.236 +static void dump_razor_set_unref(struct razor_set *set)
  16.237 +{
  16.238 +    FILE *fp;
  16.239 +    gchar *filename;
  16.240 +    void *bt[16];
  16.241 +    size_t len;
  16.242 +    struct razor_set_counter *counter;
  16.243 +    filename=g_strdup_printf("razor-set-%p",set);
  16.244 +    fp=fopen(filename,"a");
  16.245 +    g_free(filename);
  16.246 +    counter=get_razor_set_counter(set);
  16.247 +    --counter->count;
  16.248 +    fprintf(fp,"Unref %p (%d refs)\n",set,counter->count);
  16.249 +    fflush(fp);
  16.250 +    len=backtrace(bt,G_N_ELEMENTS(bt));
  16.251 +    backtrace_symbols_fd(bt,len,fileno(fp));
  16.252 +    fprintf(fp,"\n");
  16.253 +    fclose(fp);
  16.254 +}
  16.255 +
  16.256 +static void dump_razor_set_peek(struct razor_set *set)
  16.257 +{
  16.258 +    FILE *fp;
  16.259 +    gchar *filename;
  16.260 +    void *bt[16];
  16.261 +    size_t len;
  16.262 +    struct razor_set_counter *counter;
  16.263 +    filename=g_strdup_printf("razor-set-%p",set);
  16.264 +    fp=fopen(filename,"a");
  16.265 +    g_free(filename);
  16.266 +    counter=get_razor_set_counter(set);
  16.267 +    fprintf(fp,"Peek %p (%d refs)\n",set,counter->count);
  16.268 +    fflush(fp);
  16.269 +    len=backtrace(bt,G_N_ELEMENTS(bt));
  16.270 +    backtrace_symbols_fd(bt,len,fileno(fp));
  16.271 +    fprintf(fp,"\n");
  16.272 +    fclose(fp);
  16.273 +}
  16.274 +
  16.275 +struct razor_set *razor_set_create_without_root(void)
  16.276 +{
  16.277 +    static struct razor_set *(*next)(void);
  16.278 +    struct razor_set *set;
  16.279 +    if (!next)
  16.280 +	next=dlsym(RTLD_NEXT,"razor_set_create_without_root");
  16.281 +    set=(*next)();
  16.282 +    dump_razor_set_ref(set);
  16.283 +    return set;
  16.284 +}
  16.285 +
  16.286 +struct razor_set *razor_set_create(void)
  16.287 +{
  16.288 +    static struct razor_set *(*next)(void);
  16.289 +    struct razor_set *set;
  16.290 +    if (!next)
  16.291 +	next=dlsym(RTLD_NEXT,"razor_set_create");
  16.292 +    set=(*next)();
  16.293 +    dump_razor_set_ref(set);
  16.294 +    return set;
  16.295 +}
  16.296 +
  16.297 +struct razor_set *razor_set_open(const char *uri,enum razor_set_flags flags,
  16.298 +  struct razor_error **error)
  16.299 +{
  16.300 +    static struct razor_set *(*next)(const char *uri,enum razor_set_flags flags,
  16.301 +      struct razor_error **error);
  16.302 +    struct razor_set *set;
  16.303 +    if (!next)
  16.304 +	next=dlsym(RTLD_NEXT,"razor_set_open");
  16.305 +    set=(*next)(uri,flags,error);
  16.306 +    dump_razor_set_ref(set);
  16.307 +    return set;
  16.308 +}
  16.309 +
  16.310 +void razor_set_unref(struct razor_set *set)
  16.311 +{
  16.312 +    static void (*next)(struct razor_set *set);
  16.313 +    if (!next)
  16.314 +	next=dlsym(RTLD_NEXT,"razor_set_unref");
  16.315 +    if (!set)
  16.316 +	abort();
  16.317 +    dump_razor_set_unref(set);
  16.318 +    (*next)(set);
  16.319 +}
  16.320 +
  16.321 +struct razor_set *razor_set_ref(struct razor_set *set)
  16.322 +{
  16.323 +    static struct razor_set *(*next)(struct razor_set *set);
  16.324 +    if (!next)
  16.325 +	next=dlsym(RTLD_NEXT,"razor_set_ref");
  16.326 +    (*next)(set);
  16.327 +    dump_razor_set_ref(set);
  16.328 +    return set;
  16.329 +}
  16.330 +
  16.331 +struct razor_set *
  16.332 +  razor_install_iterator_commit_set(struct razor_install_iterator *ii)
  16.333 +{
  16.334 +    static struct razor_set *(*next)(struct razor_install_iterator *ii);
  16.335 +    struct razor_set *set;
  16.336 +    if (!next)
  16.337 +	next=dlsym(RTLD_NEXT,"razor_install_iterator_commit_set");
  16.338 +    set=(*next)(ii);
  16.339 +    dump_razor_set_ref(set);
  16.340 +    return set;
  16.341 +}
  16.342 +
  16.343 +struct razor_set *razor_transaction_commit(struct razor_transaction *trans)
  16.344 +{
  16.345 +    static struct razor_set *(*next)(struct razor_transaction *trans);
  16.346 +    struct razor_set *set;
  16.347 +    if (!next)
  16.348 +	next=dlsym(RTLD_NEXT,"razor_transaction_commit");
  16.349 +    set=(*next)(trans);
  16.350 +    dump_razor_set_ref(set);
  16.351 +    return set;
  16.352 +}
  16.353 +
  16.354 +struct razor_set *razor_importer_finish(struct razor_importer *importer)
  16.355 +{
  16.356 +    static struct razor_set *(*next)(struct razor_importer *importer);
  16.357 +    struct razor_set *set;
  16.358 +    if (!next)
  16.359 +	next=dlsym(RTLD_NEXT,"razor_importer_finish");
  16.360 +    set=(*next)(importer);
  16.361 +    dump_razor_set_ref(set);
  16.362 +    return set;
  16.363 +}
  16.364 +
  16.365 +struct razor_set *razor_root_open_read_only(const char *root_uri,
  16.366 +  struct razor_error **error)
  16.367 +{
  16.368 +    static struct razor_set *(*next)(const char *root_uri,
  16.369 +      struct razor_error **error);
  16.370 +    struct razor_set *set;
  16.371 +    if (!next)
  16.372 +	next=dlsym(RTLD_NEXT,"razor_root_open_read_only");
  16.373 +    set=(*next)(root_uri,error);
  16.374 +    dump_razor_set_ref(set);
  16.375 +    return set;
  16.376 +}
  16.377 +
  16.378 +struct razor_set *razor_root_get_system_set(struct razor_root *root)
  16.379 +{
  16.380 +    static struct razor_set *(*next)(struct razor_root *root);
  16.381 +    struct razor_set *set;
  16.382 +    if (!next)
  16.383 +	next=dlsym(RTLD_NEXT,"razor_root_get_system_set");
  16.384 +    set=(*next)(root);
  16.385 +    dump_razor_set_peek(set);
  16.386 +    return set;
  16.387 +}
    17.1 --- a/plover/transaction.c	Fri Jul 08 08:33:44 2016 +0100
    17.2 +++ b/plover/transaction.c	Sat Jul 16 11:07:18 2016 +0100
    17.3 @@ -429,45 +429,31 @@
    17.4    const char *install_root,GError **error)
    17.5  {
    17.6      PloverPackageSet *installed;
    17.7 -    const char *install_uri;
    17.8 -    gchar *install_path;
    17.9 +    const char *root;
   17.10 +    char *install_uri;
   17.11      GFile *file;
   17.12      gboolean retval;
   17.13      g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
   17.14      if (!install_root)
   17.15      {
   17.16 -	install_uri=g_getenv("RAZOR_ROOT");
   17.17 -	if (install_uri)
   17.18 -	{
   17.19 -	    file=g_file_new_for_uri(install_uri);
   17.20 -	    install_path=g_file_get_path(file);
   17.21 -	    g_object_unref(file);
   17.22 -	    if (!install_path)
   17.23 -	    {
   17.24 -		g_set_error(error,PLOVER_GENERAL_ERROR,
   17.25 -		  PLOVER_GENERAL_ERROR_FAILED,
   17.26 -		  "%s: Not a local URI",install_uri);
   17.27 -		return FALSE;
   17.28 -	    }
   17.29 -	}
   17.30 -	else
   17.31 -	    install_path=g_strdup("/");
   17.32 +	root=g_getenv("RAZOR_ROOT");
   17.33 +	install_uri=strdup(root?root:"file:/");
   17.34      }
   17.35      else
   17.36 -	install_path=g_strdup(install_root);
   17.37 -    if (transaction->installed && !g_strcmp0(install_path,
   17.38 +	install_uri=razor_path_to_uri(install_root);
   17.39 +    if (transaction->installed && !g_strcmp0(install_uri,
   17.40        plover_package_set_get_install_root(transaction->installed)))
   17.41      {
   17.42 -	g_free(install_path);
   17.43 +	free(install_uri);
   17.44  	return TRUE;
   17.45      }
   17.46      installed=plover_package_set_new();
   17.47 -    retval=plover_package_set_open(installed,install_path,TRUE,error);
   17.48 +    retval=plover_package_set_open(installed,install_uri,TRUE,error);
   17.49      if (retval)
   17.50  	plover_transaction_set_installed(transaction,installed);
   17.51      else
   17.52  	g_object_unref(installed);
   17.53 -    g_free(install_path);
   17.54 +    free(install_uri);
   17.55      return retval;
   17.56  }
   17.57  
   17.58 @@ -514,13 +500,10 @@
   17.59    const char *base,GError **error)
   17.60  {
   17.61      gboolean retval;
   17.62 -    gchar *base_uri;
   17.63 -    GFile *file;
   17.64 -    file=g_file_new_for_path(base);
   17.65 -    base_uri=g_file_get_uri(file);
   17.66 -    g_object_unref(file);
   17.67 +    char *base_uri;
   17.68 +    base_uri=razor_path_to_uri(base);
   17.69      retval=plover_transaction_set_upstream_from_yum_uri(transaction,base_uri,error);
   17.70 -    g_free(base_uri);
   17.71 +    free(base_uri);
   17.72      return retval;
   17.73  }
   17.74  
   17.75 @@ -783,8 +766,8 @@
   17.76  {
   17.77      int i,changed,is_leaf;
   17.78      uint32_t flags;
   17.79 -    gchar *install_path;
   17.80 -    const char *install_uri;
   17.81 +    const char *root;
   17.82 +    char *install_uri;
   17.83      const char *name,*version,*maybe_unused_name;
   17.84      struct razor_set *system,*upstream;
   17.85      struct razor_transaction *trans;
   17.86 @@ -800,29 +783,16 @@
   17.87      struct razor_property_iterator *removed_props;
   17.88      if (!pkgs)
   17.89  	return plover_transaction_new_remove(NULL,error);
   17.90 -    install_uri=g_getenv("RAZOR_ROOT");
   17.91 -    if (install_uri)
   17.92 -    {
   17.93 -	file=g_file_new_for_uri(install_uri);
   17.94 -	install_path=g_file_get_path(file);
   17.95 -	g_object_unref(file);
   17.96 -	if (!install_path)
   17.97 -	{
   17.98 -	    g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
   17.99 -	      "%s: Not a local URI",install_uri);
  17.100 -	    return NULL;
  17.101 -	}
  17.102 -    }
  17.103 -    else
  17.104 -	install_path=g_strdup("/");
  17.105 +    root=g_getenv("RAZOR_ROOT");
  17.106 +    install_uri=strdup(root?root:"file:/");
  17.107      installed=plover_package_set_new();
  17.108 -    if (!plover_package_set_open(installed,install_path,TRUE,error))
  17.109 +    if (!plover_package_set_open(installed,install_uri,TRUE,error))
  17.110      {
  17.111  	g_object_unref(installed);
  17.112 -	g_free(install_path);
  17.113 +	free(install_uri);
  17.114  	return NULL;
  17.115      }
  17.116 -    g_free(install_path);
  17.117 +    free(install_uri);
  17.118      system=plover_package_set_get_razor(installed);
  17.119      package_names=plover_vector_new();
  17.120      for(i=0;pkgs[i];i++)
    18.1 --- a/plover/util.c	Fri Jul 08 08:33:44 2016 +0100
    18.2 +++ b/plover/util.c	Sat Jul 16 11:07:18 2016 +0100
    18.3 @@ -29,8 +29,9 @@
    18.4  #include "config.h"
    18.5  #include "plover.h"
    18.6  
    18.7 -gchar *plover_default_prefix_for_vendor(const char *vendor)
    18.8 +gchar *plover_comps_get_default_prefix(struct comps *comps)
    18.9  {
   18.10 +    const char *vendor_prefix;
   18.11  #ifdef WIN32
   18.12      /*
   18.13       * We want to sidestep any redirecting that MS-Windows may
   18.14 @@ -55,15 +56,17 @@
   18.15  	  buf);
   18.16  	program_files=buf;
   18.17      }
   18.18 -    return g_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL);
   18.19 +    vendor_prefix=program_files;
   18.20  #else
   18.21 -    const char *vendor_prefix;
   18.22      vendor_prefix=g_getenv("PLOVER_VENDOR_PREFIX");
   18.23 +#endif
   18.24      if (!vendor_prefix)
   18.25  	return NULL;
   18.26 +    else if (!comps)
   18.27 +	return g_build_filename(vendor_prefix,"Plover",NULL);
   18.28      else
   18.29 -	return g_build_filename(vendor_prefix,vendor?vendor:"Plover",NULL);
   18.30 -#endif
   18.31 +	return g_build_filename(vendor_prefix,
   18.32 +	  comps->vendor?comps->vendor:"Plover",comps->distribution,NULL);
   18.33  }
   18.34  
   18.35  gchar *plover_pre_install_prefix(void)
    19.1 --- a/setup/setup.c	Fri Jul 08 08:33:44 2016 +0100
    19.2 +++ b/setup/setup.c	Sat Jul 16 11:07:18 2016 +0100
    19.3 @@ -1,5 +1,5 @@
    19.4  /*
    19.5 - * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
    19.6 + * Copyright (C) 2009, 2011, 2016  J. Ali Harlow <ali@juiblex.co.uk>
    19.7   *
    19.8   * This program is free software; you can redistribute it and/or modify
    19.9   * it under the terms of the GNU General Public License as published by
   19.10 @@ -33,25 +33,89 @@
   19.11  
   19.12  void setup(const char *argv0)
   19.13  {
   19.14 -    char *path;
   19.15 -    gchar *s,*prefix;
   19.16 +    char *yum_uri,*local_database,*active_database,*alternate_database;
   19.17 +    gchar *s,*prefix,*distribution,*vendor_prefix;
   19.18      int ch,changed;
   19.19      struct comps *comps;
   19.20      struct comps_group *group;
   19.21      struct comps_requirement *pkg;
   19.22      struct plover_vector *packages=NULL;
   19.23      GError *error=NULL;
   19.24 -    path=plover_get_program_directory(argv0);
   19.25 -    s=g_strconcat(path,"/repodata/comps.xml",NULL);
   19.26 -    comps=plover_comps_new_from_file(s);
   19.27 +    s=plover_get_program(argv0);
   19.28 +    yum_uri=razor_path_to_uri(s);
   19.29 +    g_free(s);
   19.30 +    s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL);
   19.31 +    comps=plover_comps_new_from_uri(s,&error);
   19.32 +    g_free(s);
   19.33 +    if (g_error_matches(error,PLOVER_RAZOR_ERROR,
   19.34 +      RAZOR_GENERAL_ERROR_UNSUPPORTED_ARCHIVE))
   19.35 +    {
   19.36 +	g_clear_error(&error);
   19.37 +	free(yum_uri);
   19.38 +	s=plover_get_program_directory(argv0);
   19.39 +	yum_uri=razor_path_to_uri(s);
   19.40 +	g_free(s);
   19.41 +	s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL);
   19.42 +	comps=plover_comps_new_from_uri(s,&error);
   19.43 +    }
   19.44      if (!comps)
   19.45      {
   19.46 -	perror(s);
   19.47 +	fprintf(stderr,"%s\n",error->message);
   19.48 +	g_error_free(error);
   19.49  	exit(1);
   19.50      }
   19.51 -    g_free(s);
   19.52 -    prefix=plover_default_prefix_for_vendor(comps->vendor);
   19.53 -    if (!plover_installed_files_match_prefix(prefix))
   19.54 +    prefix=plover_comps_get_default_prefix(comps);
   19.55 +    if (prefix)
   19.56 +    {
   19.57 +	s=g_strconcat(prefix,"/var/lib/razor",NULL);
   19.58 +	local_database=razor_path_to_uri(s);
   19.59 +	g_free(s);
   19.60 +    }
   19.61 +    else
   19.62 +	local_database=NULL;
   19.63 +    switch(comps->database)
   19.64 +    {
   19.65 +	case COMPS_DATABASE_DISTRIBUTION_LOCAL:
   19.66 +	    active_database=local_database;
   19.67 +	    alternate_database=NULL;
   19.68 +	    break;
   19.69 +	case COMPS_DATABASE_GLOBAL:
   19.70 +	    active_database=NULL;
   19.71 +	    alternate_database=local_database;
   19.72 +	    break;
   19.73 +    }
   19.74 +    if (prefix)
   19.75 +    {
   19.76 +	distribution=g_strdup(comps->distribution);
   19.77 +	plover_comps_set_distribution(comps,NULL);
   19.78 +	vendor_prefix=plover_comps_get_default_prefix(comps);
   19.79 +	plover_comps_set_distribution(comps,distribution);
   19.80 +	g_free(distribution);
   19.81 +	razor_set_database_uri(alternate_database);
   19.82 +	if (plover_installed_files_match_prefix(vendor_prefix)==1)
   19.83 +	{
   19.84 +	    printf("There is an existing installation under %s\n"
   19.85 +	      "which is not compatible with this distribution. In order\n"
   19.86 +	      "to continue, the existing installation must be uninstalled.\n"
   19.87 +	      "Do you want to remove all packages in the existing installion? ",
   19.88 +	      prefix);
   19.89 +	    ch=getchar();
   19.90 +	    if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n')
   19.91 +		exit(1);
   19.92 +	    while(ch!='\n' && ch!=EOF)
   19.93 +		ch=getchar();
   19.94 +	    if (plover_remove(NULL,&error))
   19.95 +	    {
   19.96 +		fprintf(stderr,"%s\n",error->message);
   19.97 +		g_error_free(error);
   19.98 +		exit(1);
   19.99 +	    }
  19.100 +	}
  19.101 +	g_free(vendor_prefix);
  19.102 +    }
  19.103 +    razor_set_database_uri(active_database);
  19.104 +    free(local_database);
  19.105 +    if (prefix && !plover_installed_files_match_prefix(prefix))
  19.106      {
  19.107  	printf("The existing installation is not under %s\n"
  19.108  	  "In order to continue, all the existing packages must be removed.\n"
  19.109 @@ -98,7 +162,7 @@
  19.110  	fprintf(stderr,"No packages to install\n");
  19.111  	exit(1);
  19.112      }
  19.113 -    if (!plover_install(path,prefix,packages->strings,&error))
  19.114 +    if (!plover_install_uri(yum_uri,prefix,packages->strings,&error))
  19.115      {
  19.116  	fprintf(stderr,"%s\n",error->message);
  19.117  	g_error_free(error);
  19.118 @@ -106,7 +170,7 @@
  19.119      }
  19.120      plover_vector_free(packages);
  19.121      g_free(prefix);
  19.122 -    free(path);
  19.123 +    free(yum_uri);
  19.124  }
  19.125  
  19.126  int main(int argc,char **argv)
    20.1 --- a/tests/Makefile.am	Fri Jul 08 08:33:44 2016 +0100
    20.2 +++ b/tests/Makefile.am	Sat Jul 16 11:07:18 2016 +0100
    20.3 @@ -2,7 +2,7 @@
    20.4  
    20.5  EXTRA_DIST = zsh.spec zsh2.spec zip.spec zap.spec filesystem.spec zappy.spec \
    20.6      zappy2.spec unsatisfiable.spec uninstallable.spec badpostun.spec comps.xml \
    20.7 -    glib.supp.in README xvfb-run
    20.8 +    distribution-local-comps.xml glib.supp.in README xvfb-run
    20.9  
   20.10  pkg_V_rpmbuild = $(pkg_v_rpmbuild_$(V))
   20.11  pkg_v_rpmbuild_ = $(pkg_v_rpmbuild_$(AM_DEFAULT_VERBOSITY))
   20.12 @@ -13,7 +13,8 @@
   20.13  if HAVE_CHECK_TOOLS
   20.14  
   20.15  noinst_DATA = glib.supp yum-repo-test-dir/repodata/primary.xml.gz \
   20.16 -	primary.xml.gz razor-test-dir/var/lib/razor/system.rzdb
   20.17 +	distribution-local-test-dir/repodata/primary.xml.gz \
   20.18 +	razor-test-dir/var/lib/razor/system.rzdb
   20.19  
   20.20  if HAVE_VALGRIND_3_9
   20.21  %.supp: %.supp.in
   20.22 @@ -23,6 +24,22 @@
   20.23  	grep -v '^ *match-leak-kinds: ' $< > $@
   20.24  endif
   20.25  
   20.26 +distribution-local-test-dir/repodata/primary.xml.gz: filesystem.spec \
   20.27 +    zappy.spec Makefile
   20.28 +	rm -rf rpmbuild distribution-local-test-dir
   20.29 +	mkdir -p rpmbuild/BUILD rpmbuild/RPMS
   20.30 +	$(BUILD_RPM) $(srcdir)/filesystem.spec
   20.31 +	$(BUILD_RPM) $(srcdir)/zappy.spec
   20.32 +	mkdir -p distribution-local-test-dir/Packages
   20.33 +	mv rpmbuild/RPMS/noarch/*.rpm distribution-local-test-dir/Packages
   20.34 +	rm -rf rpmbuild
   20.35 +	cp $(srcdir)/distribution-local-comps.xml \
   20.36 +	  distribution-local-test-dir/comps.xml
   20.37 +	$(CREATEREPO) --simple-md-filenames -g comps.xml \
   20.38 +	  distribution-local-test-dir
   20.39 +	mv distribution-local-test-dir/comps.xml \
   20.40 +	  distribution-local-test-dir/repodata
   20.41 +
   20.42  yum-repo-test-dir/repodata/primary.xml.gz: zsh.spec zsh2.spec zip.spec \
   20.43      zap.spec filesystem.spec zappy.spec zappy2.spec unsatisfiable.spec \
   20.44      uninstallable.spec badpostun.spec Makefile
   20.45 @@ -45,13 +62,7 @@
   20.46  	$(CREATEREPO) --simple-md-filenames -g comps.xml yum-repo-test-dir
   20.47  	mv yum-repo-test-dir/comps.xml yum-repo-test-dir/repodata
   20.48  
   20.49 -primary.xml.gz: yum-repo-test-dir/repodata/primary.xml.gz
   20.50 -	cp yum-repo-test-dir/repodata/primary.xml.gz \
   20.51 -	  yum-repo-test-dir/repodata/filelists.xml.gz .
   20.52 -	rm -rf rpms
   20.53 -	ln -s yum-repo-test-dir/rpms .
   20.54 -
   20.55 -razor-test-dir/var/lib/razor/system.rzdb: primary.xml.gz
   20.56 +razor-test-dir/var/lib/razor/system.rzdb: yum-repo-test-dir/repodata/primary.xml.gz
   20.57  	$(RM) -r razor-test-dir
   20.58  	$(RAZOR) --root=file:razor-test-dir init
   20.59  	$(RAZOR) --url=file://localhost`pwd`/yum-repo-test-dir \
   20.60 @@ -71,7 +82,7 @@
   20.61  	done
   20.62  
   20.63  clean-local:
   20.64 -	rm -rf yum-repo-test-dir razor-test-dir
   20.65 -	rm -f primary.xml.gz filelists.xml.gz rpms rawhide.rzdb
   20.66 +	rm -rf yum-repo-test-dir distribution-local-test-dir razor-test-dir
   20.67 +	rm -f rawhide.rzdb
   20.68  
   20.69  CLEANFILES = glib.supp
    21.1 --- a/tests/plover-gtk/test-transactionhelper.c	Fri Jul 08 08:33:44 2016 +0100
    21.2 +++ b/tests/plover-gtk/test-transactionhelper.c	Sat Jul 16 11:07:18 2016 +0100
    21.3 @@ -29,6 +29,16 @@
    21.4  GtkBuilder *ui;
    21.5  gboolean manual_mode=FALSE;
    21.6  
    21.7 +#if 0
    21.8 +static void complete_changed(GtkWidget *page,GParamSpec *child_property,
    21.9 +  PloverTransactionHelper *helper)
   21.10 +{
   21.11 +    g_message("complete child property for %s now %s",
   21.12 +      gtk_buildable_get_name(GTK_BUILDABLE(page)),
   21.13 +      gtk_assistant_get_page_complete(helper->assistant,page)?"TRUE":"FALSE");
   21.14 +}
   21.15 +#endif
   21.16 +
   21.17  PloverTransactionHelper *get_transaction_helper(void)
   21.18  {
   21.19      const char *dir;
   21.20 @@ -43,6 +53,23 @@
   21.21      g_free(s);
   21.22      helper=plover_transaction_helper_new(ui);
   21.23      g_object_unref(ui);
   21.24 +#if 0
   21.25 +    if (helper->assistant)
   21.26 +    {
   21.27 +	GtkWidget *page;
   21.28 +	int i;
   21.29 +	for(i=gtk_assistant_get_n_pages(helper->assistant)-1;i>=0;i--)
   21.30 +	{
   21.31 +	    page=gtk_assistant_get_nth_page(helper->assistant,i);
   21.32 +	    g_signal_connect(page,"child-notify::complete",
   21.33 +	      G_CALLBACK(complete_changed),helper);
   21.34 +	    g_message("complete child property for %s initially %s",
   21.35 +	      gtk_buildable_get_name(GTK_BUILDABLE(page)),
   21.36 +	      gtk_assistant_get_page_complete(helper->assistant,page)?
   21.37 +	      "TRUE":"FALSE");
   21.38 +	}
   21.39 +    }
   21.40 +#endif
   21.41      return helper;
   21.42  }
   21.43  
   21.44 @@ -56,6 +83,8 @@
   21.45  static void test_basic_properties(void)
   21.46  {
   21.47      const char *prefix;
   21.48 +    char *uri;
   21.49 +    gchar *default_prefix;
   21.50      GError *err=NULL;
   21.51      struct comps *comps;
   21.52      PloverTransactionHelper *helper;
   21.53 @@ -64,7 +93,9 @@
   21.54      upstream=plover_repository_new_from_yum("../yum-repo-test-dir",&err);
   21.55      if (!upstream)
   21.56  	g_error("../yum-repo-test-dir: %s",err->message);
   21.57 -    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
   21.58 +    uri=razor_path_to_uri("../razor-test-dir");
   21.59 +    installed=plover_package_set_new_from_installed(uri,&err);
   21.60 +    free(uri);
   21.61      if (!installed)
   21.62  	g_error("../razor-test-dir: %s",err->message);
   21.63      helper=get_transaction_helper();
   21.64 @@ -81,7 +112,12 @@
   21.65      g_assert(plover_comps_lookup_group(comps,"base"));
   21.66      prefix=plover_transaction_helper_get_prefix(helper,&err);
   21.67      g_assert(!err);
   21.68 -    g_assert_cmpstr(prefix,==,plover_default_prefix_for_vendor("Acme Corporation"));
   21.69 +    comps=plover_comps_new();
   21.70 +    plover_comps_set_vendor(comps,"Acme Corporation");
   21.71 +    default_prefix=plover_comps_get_default_prefix(comps);
   21.72 +    plover_comps_free(comps);
   21.73 +    g_assert_cmpstr(prefix,==,default_prefix);
   21.74 +    g_free(default_prefix);
   21.75      g_assert(!plover_transaction_helper_get_visible(helper));
   21.76      g_assert(!plover_transaction_helper_get_error(helper,NULL));
   21.77      g_object_unref(upstream);
   21.78 @@ -91,21 +127,21 @@
   21.79  
   21.80  static void test_install_group(void)
   21.81  {
   21.82 -    gchar *root,*root_uri;
   21.83 +    gchar *root;
   21.84      GError *err=NULL;
   21.85 -    GFile *file;
   21.86 +    char *uri;
   21.87      PloverPackageSet *installed;
   21.88      PloverTransactionHelper *helper;
   21.89      root=g_strdup("razor-test-dir-XXXXXX");
   21.90      g_assert(mkdtemp(root));
   21.91 -    file=g_file_new_for_path(root);
   21.92 +    uri=razor_path_to_uri(root);
   21.93      g_free(root);
   21.94 -    root_uri=g_file_get_uri(file);
   21.95 -    g_object_unref(file);
   21.96 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
   21.97 -    g_free(root_uri);
   21.98 +    g_setenv("RAZOR_ROOT",uri,TRUE);
   21.99 +    free(uri);
  21.100      helper=get_transaction_helper();
  21.101 -    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
  21.102 +    uri=razor_path_to_uri("../razor-test-dir");
  21.103 +    installed=plover_package_set_new_from_installed(uri,&err);
  21.104 +    free(uri);
  21.105      if (!installed)
  21.106  	g_error("../razor-test-dir: %s",err->message);
  21.107      plover_transaction_helper_set_installed(helper,installed);
  21.108 @@ -120,20 +156,17 @@
  21.109  
  21.110  static void test_remove_group(void)
  21.111  {
  21.112 -    gchar *root,*root_uri;
  21.113 +    gchar *root;
  21.114 +    char *uri;
  21.115      GError *err=NULL;
  21.116 -    GFile *file;
  21.117      PloverPackageSet *installed;
  21.118      PloverTransactionHelper *helper;
  21.119      struct plover_vector *packages;
  21.120      char *pkgs[]={"zip",NULL};
  21.121      root=g_strdup("razor-test-dir-XXXXXX");
  21.122      g_assert(mkdtemp(root));
  21.123 -    file=g_file_new_for_path(root);
  21.124 -    root_uri=g_file_get_uri(file);
  21.125 -    g_object_unref(file);
  21.126 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.127 -    g_free(root_uri);
  21.128 +    uri=razor_path_to_uri(root);
  21.129 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.130      helper=get_transaction_helper();
  21.131      plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  21.132      packages=plover_transaction_helper_group_get_default_packages(helper,
  21.133 @@ -143,7 +176,7 @@
  21.134      if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err))
  21.135  	g_error("plover_install: %s",err->message);
  21.136      plover_vector_free(packages);
  21.137 -    installed=plover_package_set_new_from_installed(root,&err);
  21.138 +    installed=plover_package_set_new_from_installed(uri,&err);
  21.139      if (!installed)
  21.140  	g_error("%s: %s",root,err->message);
  21.141      plover_transaction_helper_set_installed(helper,installed);
  21.142 @@ -153,26 +186,26 @@
  21.143      g_assert(!err);
  21.144      g_object_unref(helper);
  21.145      g_unsetenv("RAZOR_ROOT");
  21.146 +    free(uri);
  21.147      g_free(root);
  21.148  }
  21.149  
  21.150  static void test_update(void)
  21.151  {
  21.152 -    gchar *root,*root_uri;
  21.153 +    gchar *root;
  21.154 +    char *uri;
  21.155      GError *err=NULL;
  21.156 -    GFile *file;
  21.157      PloverPackageSet *installed;
  21.158      PloverTransactionHelper *helper;
  21.159      root=g_strdup("razor-test-dir-XXXXXX");
  21.160      g_assert(mkdtemp(root));
  21.161 -    file=g_file_new_for_path(root);
  21.162 -    g_free(root);
  21.163 -    root_uri=g_file_get_uri(file);
  21.164 -    g_object_unref(file);
  21.165 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.166 -    g_free(root_uri);
  21.167 +    uri=razor_path_to_uri(root);
  21.168 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.169 +    g_free(uri);
  21.170      helper=get_transaction_helper();
  21.171 -    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
  21.172 +    uri=razor_path_to_uri("../razor-test-dir");
  21.173 +    installed=plover_package_set_new_from_installed(uri,&err);
  21.174 +    free(uri);
  21.175      if (!installed)
  21.176  	g_error("../razor-test-dir: %s",err->message);
  21.177      plover_transaction_helper_set_installed(helper,installed);
  21.178 @@ -204,6 +237,19 @@
  21.179      struct run_install_baton *baton=data;
  21.180      GtkWidget *page;
  21.181      GtkAssistant *assistant=baton->helper->assistant;
  21.182 +#if 0
  21.183 +    page=gtk_assistant_get_nth_page(assistant,
  21.184 +      gtk_assistant_get_current_page(assistant));
  21.185 +    g_message("run_install_tick: state is %s, on page %s",
  21.186 +      baton->state==RI_STATE_INIT?"INIT":
  21.187 +      baton->state==RI_STATE_SUMMARY?"SUMMARY":
  21.188 +      baton->state==RI_STATE_PROGRESS?"PROGRESS":
  21.189 +      baton->state==RI_STATE_PROGRESS_DELAY?"PROGRESS_DELAY":
  21.190 +      baton->state==RI_STATE_DONE?"DONE":
  21.191 +      baton->state==RI_STATE_FINISH?"FINISH":
  21.192 +      "Unknown",
  21.193 +      gtk_buildable_get_name(GTK_BUILDABLE(page)));
  21.194 +#endif
  21.195      switch(baton->state)
  21.196      {
  21.197  	case RI_STATE_INIT:
  21.198 @@ -215,6 +261,7 @@
  21.199  	case RI_STATE_SUMMARY:
  21.200  	    if (gtk_assistant_get_current_page(assistant)<1)
  21.201  		return TRUE;
  21.202 +	    g_assert(gtk_widget_is_sensitive(assistant->apply));
  21.203  	    if (!manual_mode)
  21.204  		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  21.205  	    break;
  21.206 @@ -254,23 +301,20 @@
  21.207  
  21.208  static void test_run_install(void)
  21.209  {
  21.210 -    gchar *root,*root_uri;
  21.211 +    gchar *root;
  21.212 +    char *uri;
  21.213      GError *err=NULL;
  21.214 -    GFile *file;
  21.215      struct plover_vector *packages;
  21.216      PloverPackageSet *installed;
  21.217      PloverTransactionHelper *helper;
  21.218      struct run_install_baton baton={0,};
  21.219      root=g_strdup("razor-test-dir-XXXXXX");
  21.220      g_assert(mkdtemp(root));
  21.221 -    file=g_file_new_for_path(root);
  21.222 -    root_uri=g_file_get_uri(file);
  21.223 -    g_object_unref(file);
  21.224 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.225 -    g_free(root_uri);
  21.226 +    uri=razor_path_to_uri(root);
  21.227 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.228      helper=get_transaction_helper();
  21.229      installed=plover_package_set_new();
  21.230 -    if (!plover_package_set_open(installed,root,TRUE,&err))
  21.231 +    if (!plover_package_set_open(installed,uri,TRUE,&err))
  21.232  	g_error("%s: %s",root,err->message);
  21.233      plover_transaction_helper_set_installed(helper,installed);
  21.234      g_object_unref(installed);
  21.235 @@ -287,6 +331,7 @@
  21.236      gtk_main();
  21.237      g_object_unref(helper);
  21.238      g_unsetenv("RAZOR_ROOT");
  21.239 +    free(uri);
  21.240      g_free(root);
  21.241  }
  21.242  
  21.243 @@ -320,6 +365,7 @@
  21.244  	case RR_STATE_SUMMARY:
  21.245  	    if (gtk_assistant_get_current_page(assistant)<1)
  21.246  		return TRUE;
  21.247 +	    g_assert(gtk_widget_is_sensitive(assistant->apply));
  21.248  	    if (!manual_mode)
  21.249  		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  21.250  	    break;
  21.251 @@ -359,20 +405,17 @@
  21.252  
  21.253  static void test_run_remove(void)
  21.254  {
  21.255 -    gchar *root,*root_uri;
  21.256 +    gchar *root;
  21.257 +    char *uri;
  21.258      GError *err=NULL;
  21.259 -    GFile *file;
  21.260      struct plover_vector *packages;
  21.261      PloverPackageSet *installed;
  21.262      PloverTransactionHelper *helper;
  21.263      struct run_remove_baton baton={0,};
  21.264      root=g_strdup("razor-test-dir-XXXXXX");
  21.265      g_assert(mkdtemp(root));
  21.266 -    file=g_file_new_for_path(root);
  21.267 -    root_uri=g_file_get_uri(file);
  21.268 -    g_object_unref(file);
  21.269 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.270 -    g_free(root_uri);
  21.271 +    uri=razor_path_to_uri(root);
  21.272 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.273      helper=get_transaction_helper();
  21.274      plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  21.275      packages=
  21.276 @@ -383,7 +426,7 @@
  21.277  	g_error("plover_install: %s",err->message);
  21.278      plover_vector_free(packages);
  21.279      installed=plover_package_set_new();
  21.280 -    if (!plover_package_set_open(installed,root,TRUE,&err))
  21.281 +    if (!plover_package_set_open(installed,uri,TRUE,&err))
  21.282  	g_error("%s: %s",root,err->message);
  21.283      plover_transaction_helper_set_installed(helper,installed);
  21.284      g_object_unref(installed);
  21.285 @@ -396,6 +439,7 @@
  21.286      gtk_main();
  21.287      g_object_unref(helper);
  21.288      g_unsetenv("RAZOR_ROOT");
  21.289 +    free(uri);
  21.290      g_free(root);
  21.291  }
  21.292  
  21.293 @@ -429,6 +473,7 @@
  21.294  	case RU_STATE_SUMMARY:
  21.295  	    if (gtk_assistant_get_current_page(assistant)<1)
  21.296  		return TRUE;
  21.297 +	    g_assert(gtk_widget_is_sensitive(assistant->apply));
  21.298  	    if (!manual_mode)
  21.299  		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  21.300  	    break;
  21.301 @@ -468,9 +513,9 @@
  21.302  
  21.303  static void test_run_update(void)
  21.304  {
  21.305 -    gchar *root,*root_uri;
  21.306 +    gchar *root;
  21.307 +    char *uri;
  21.308      GError *err=NULL;
  21.309 -    GFile *file;
  21.310      struct razor_importer *importer;
  21.311      struct razor_set *downgraded;
  21.312      struct razor_atomic *atomic;
  21.313 @@ -480,15 +525,12 @@
  21.314      struct run_update_baton baton={0,};
  21.315      root=g_strdup("razor-test-dir-XXXXXX");
  21.316      g_assert(mkdtemp(root));
  21.317 -    file=g_file_new_for_path(root);
  21.318 -    root_uri=g_file_get_uri(file);
  21.319 -    g_object_unref(file);
  21.320 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.321 -    g_free(root_uri);
  21.322 +    uri=razor_path_to_uri(root);
  21.323 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.324      helper=get_transaction_helper();
  21.325      plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  21.326      installed=plover_package_set_new();
  21.327 -    if (!plover_package_set_open(installed,root,TRUE,&err))
  21.328 +    if (!plover_package_set_open(installed,uri,TRUE,&err))
  21.329  	g_error("%s: %s",root,err->message);
  21.330      importer=razor_importer_create();
  21.331      razor_importer_begin_package(importer,"zappy","0-1","noarch");
  21.332 @@ -513,6 +555,7 @@
  21.333      gtk_main();
  21.334      g_object_unref(helper);
  21.335      g_unsetenv("RAZOR_ROOT");
  21.336 +    free(uri);
  21.337      g_free(root);
  21.338  }
  21.339  
  21.340 @@ -590,8 +633,8 @@
  21.341  static void test_check_vendor(void)
  21.342  {
  21.343      int fh;
  21.344 -    gchar *root,*root_uri,*s;
  21.345 -    GFile *file;
  21.346 +    gchar *root,*s;
  21.347 +    char *uri;
  21.348      GError *err=NULL;
  21.349      struct razor_importer *importer;
  21.350      struct razor_set *downgraded;
  21.351 @@ -599,19 +642,17 @@
  21.352      struct plover_vector *packages;
  21.353      PloverPackageSet *installed;
  21.354      PloverTransactionHelper *helper;
  21.355 -    struct run_update_baton baton={0,};
  21.356 +    struct check_vendor_baton baton={0,};
  21.357      g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE);
  21.358      root=g_strdup("razor-test-dir-XXXXXX");
  21.359      g_assert(mkdtemp(root));
  21.360 -    file=g_file_new_for_path(root);
  21.361 -    root_uri=g_file_get_uri(file);
  21.362 -    g_object_unref(file);
  21.363 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.364 +    uri=razor_path_to_uri(root);
  21.365 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.366      helper=get_transaction_helper();
  21.367      plover_transaction_helper_set_check_vendor(helper,TRUE);
  21.368      plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  21.369      installed=plover_package_set_new();
  21.370 -    if (!plover_package_set_open(installed,root,TRUE,&err))
  21.371 +    if (!plover_package_set_open(installed,uri,TRUE,&err))
  21.372  	g_error("%s: %s",root,err->message);
  21.373      importer=razor_importer_create();
  21.374      razor_importer_begin_package(importer,"zappy","0-1","noarch");
  21.375 @@ -622,8 +663,8 @@
  21.376      razor_importer_finish_package(importer);
  21.377      downgraded=razor_importer_finish(importer);
  21.378      atomic=razor_atomic_open("Add downgraded packages");
  21.379 -    razor_atomic_make_dirs(atomic,root_uri,"/test/bin/zappy");
  21.380 -    s=g_build_filename(root_uri,"test/bin/zappy",NULL);
  21.381 +    razor_atomic_make_dirs(atomic,uri,"/test/bin/zappy");
  21.382 +    s=g_build_filename(uri,"test/bin/zappy",NULL);
  21.383      fh=razor_atomic_create_file(atomic,s,S_IRWXU|S_IRWXG|S_IRWXO);
  21.384      g_free(s);
  21.385      razor_atomic_close(atomic,fh);
  21.386 @@ -644,10 +685,139 @@
  21.387      g_object_unref(helper);
  21.388      g_unsetenv("RAZOR_ROOT");
  21.389      g_free(root);
  21.390 -    g_free(root_uri);
  21.391 +    free(uri);
  21.392      g_unsetenv("PLOVER_VENDOR_PREFIX");
  21.393  }
  21.394  
  21.395 +static gchar *create_new_root_and_install(gchar **prefix_p,char **pkgs)
  21.396 +{
  21.397 +    gchar *root,*prefix;
  21.398 +    char *uri;
  21.399 +    GError *err=NULL;
  21.400 +    struct comps *comps;
  21.401 +    PloverTransaction *transaction;
  21.402 +    root=g_strdup("razor-test-dir-XXXXXX");
  21.403 +    g_assert(mkdtemp(root));
  21.404 +    uri=razor_path_to_uri(root);
  21.405 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.406 +    free(uri);
  21.407 +    uri=razor_path_to_uri("../yum-repo-test-dir/repodata/comps.xml");
  21.408 +    comps=plover_comps_new_from_uri(uri,&err);
  21.409 +    free(uri);
  21.410 +    if (!comps)
  21.411 +	g_error("../yum-repo-test-dir/repodata/comps.xml: %s",err->message);
  21.412 +    prefix=plover_comps_get_default_prefix(comps);
  21.413 +    plover_comps_free(comps);
  21.414 +    transaction=plover_transaction_new_install("../yum-repo-test-dir",prefix,
  21.415 +      pkgs,&err);
  21.416 +    if (!transaction)
  21.417 +	g_error("../yum-repo-test-dir: %s",err->message);
  21.418 +    g_assert(plover_transaction_commit(transaction,NULL,NULL));
  21.419 +    g_object_unref(transaction);
  21.420 +    fflush(stdout);
  21.421 +    if (prefix_p)
  21.422 +	*prefix_p=prefix;
  21.423 +    else
  21.424 +	g_free(prefix);
  21.425 +    return root;
  21.426 +}
  21.427 +
  21.428 +static check_file(const char *root,const char *path)
  21.429 +{
  21.430 +    gchar *s;
  21.431 +    s=g_build_filename(root,path,NULL);
  21.432 +    g_assert(g_file_test(s,G_FILE_TEST_EXISTS));
  21.433 +    g_free(s);
  21.434 +}
  21.435 +
  21.436 +static check_no_file(const char *root,const char *path)
  21.437 +{
  21.438 +    gchar *s;
  21.439 +    s=g_build_filename(root,path,NULL);
  21.440 +    g_assert(!g_file_test(s,G_FILE_TEST_EXISTS));
  21.441 +    g_free(s);
  21.442 +}
  21.443 +
  21.444 +/*
  21.445 + * Test that installing from a repository which is marked as distribution-local
  21.446 + * on top of an existing global installation works if prefix is NULL
  21.447 + * (which is the case on UNIX if PLOVER_VENDOR_PREFIX is not set).
  21.448 + */
  21.449 +static void test_unprefixed_distribution_local(void)
  21.450 +{
  21.451 +    gchar *root;
  21.452 +    GError *err=NULL;
  21.453 +    char *pkgs[]={"zap",NULL};
  21.454 +    struct plover_vector *packages;
  21.455 +    PloverPackageSet *installed;
  21.456 +    PloverTransactionHelper *helper;
  21.457 +    struct run_install_baton baton={0,};
  21.458 +    g_unsetenv("PLOVER_VENDOR_PREFIX");
  21.459 +    root=create_new_root_and_install(NULL,pkgs);
  21.460 +    check_file(root,"/usr/bin/zap");
  21.461 +    helper=get_transaction_helper();
  21.462 +    plover_transaction_helper_set_check_vendor(helper,TRUE);
  21.463 +    plover_transaction_helper_set_base(helper,"../distribution-local-test-dir");
  21.464 +    packages=plover_vector_new();
  21.465 +    plover_vector_append(packages,"zappy");
  21.466 +    if (!plover_transaction_helper_install_packages(helper,packages,&err))
  21.467 +	g_error("zappy: %s",err->message);
  21.468 +    g_assert(!err);
  21.469 +    plover_vector_free(packages);
  21.470 +    plover_transaction_helper_present(helper);
  21.471 +    baton.helper=helper;
  21.472 +    baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,&baton,NULL);
  21.473 +    gtk_main();
  21.474 +    g_object_unref(helper);
  21.475 +    check_file(root,"/usr/bin/zappy");
  21.476 +    g_free(root);
  21.477 +    g_unsetenv("RAZOR_ROOT");
  21.478 +}
  21.479 +
  21.480 +/*
  21.481 + * Test that installing from a repository which is marked as distribution-local
  21.482 + * on top of an existing global installation requires removing the existing
  21.483 + * installation if prefix is non-NULL (which is the case if PLOVER_VENDOR_PREFIX
  21.484 + * is set).
  21.485 + */
  21.486 +static void test_prefixed_distribution_local(void)
  21.487 +{
  21.488 +    gchar *root,*s;
  21.489 +    gchar *prefix;
  21.490 +    GError *err=NULL;
  21.491 +    char *pkgs[]={"zap",NULL};
  21.492 +    struct plover_vector *packages;
  21.493 +    PloverPackageSet *installed;
  21.494 +    PloverTransactionHelper *helper;
  21.495 +    struct check_vendor_baton baton={0,};
  21.496 +    g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE);
  21.497 +    helper=get_transaction_helper();
  21.498 +    plover_transaction_helper_set_check_vendor(helper,TRUE);
  21.499 +    plover_transaction_helper_set_base(helper,"../distribution-local-test-dir");
  21.500 +    root=create_new_root_and_install(&prefix,pkgs);
  21.501 +    s=g_build_filename(prefix,"bin/zap",NULL);
  21.502 +    check_file(root,s);
  21.503 +    g_free(s);
  21.504 +    packages=plover_vector_new();
  21.505 +    plover_vector_append(packages,"filesystem");
  21.506 +    if (!plover_transaction_helper_install_packages(helper,packages,&err))
  21.507 +	g_error("filesystem: %s",err->message);
  21.508 +    g_assert(!err);
  21.509 +    plover_vector_free(packages);
  21.510 +    plover_transaction_helper_present(helper);
  21.511 +    baton.helper=helper;
  21.512 +    baton.eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,&baton,NULL);
  21.513 +    gtk_main();
  21.514 +    g_object_unref(helper);
  21.515 +    s=g_build_filename(prefix,"bin/zap",NULL);
  21.516 +    check_no_file(root,s);
  21.517 +    g_free(s);
  21.518 +    check_no_file(root,"/media");
  21.519 +    g_free(root);
  21.520 +    g_free(prefix);
  21.521 +    g_unsetenv("RAZOR_ROOT");
  21.522 +}
  21.523 +
  21.524  struct set_error_baton {
  21.525      enum {
  21.526  	SE_STATE_INIT = 0,
  21.527 @@ -687,24 +857,24 @@
  21.528  
  21.529  static void test_set_error(void)
  21.530  {
  21.531 -    gchar *root,*root_uri;
  21.532 +    gchar *root;
  21.533 +    char *uri;
  21.534      const char *errmsg;
  21.535      GError *err=NULL;
  21.536      const GError *err2=NULL;
  21.537 -    GFile *file;
  21.538      PloverPackageSet *installed;
  21.539      PloverTransactionHelper *helper;
  21.540      struct set_error_baton baton={0,};
  21.541      root=g_strdup("razor-test-dir-XXXXXX");
  21.542      g_assert(mkdtemp(root));
  21.543 -    file=g_file_new_for_path(root);
  21.544 +    uri=razor_path_to_uri(root);
  21.545      g_free(root);
  21.546 -    root_uri=g_file_get_uri(file);
  21.547 -    g_object_unref(file);
  21.548 -    g_setenv("RAZOR_ROOT",root_uri,TRUE);
  21.549 -    g_free(root_uri);
  21.550 +    g_setenv("RAZOR_ROOT",uri,TRUE);
  21.551 +    free(uri);
  21.552      helper=get_transaction_helper();
  21.553 -    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
  21.554 +    uri=razor_path_to_uri("../razor-test-dir");
  21.555 +    installed=plover_package_set_new_from_installed(uri,&err);
  21.556 +    free(uri);
  21.557      if (!installed)
  21.558  	g_error("../razor-test-dir: %s",err->message);
  21.559      plover_transaction_helper_set_installed(helper,installed);
  21.560 @@ -759,6 +929,10 @@
  21.561      g_test_add_func("/transactionhelper/run-remove",test_run_remove);
  21.562      g_test_add_func("/transactionhelper/run-update",test_run_update);
  21.563      g_test_add_func("/transactionhelper/check-vendor",test_check_vendor);
  21.564 +    g_test_add_func("/transactionhelper/unprefixed-distribution-local",
  21.565 +      test_unprefixed_distribution_local);
  21.566 +    g_test_add_func("/transactionhelper/prefixed-distribution-local",
  21.567 +      test_prefixed_distribution_local);
  21.568      g_test_add_func("/transactionhelper/set-error",test_set_error);
  21.569      retval=g_test_run();
  21.570      return retval;
    22.1 --- a/tests/plover/test-packageset.c	Fri Jul 08 08:33:44 2016 +0100
    22.2 +++ b/tests/plover/test-packageset.c	Sat Jul 16 11:07:18 2016 +0100
    22.3 @@ -55,6 +55,7 @@
    22.4      struct razor_set *set;
    22.5      struct razor_package *pkg;
    22.6      struct razor_package_iterator *iter;
    22.7 +    struct comps *comps;
    22.8      PloverPackage *package;
    22.9      GError *err=NULL;
   22.10      const char *prefix;
   22.11 @@ -79,7 +80,10 @@
   22.12      if (!prefix && err)
   22.13  	g_error("plover_package_set_guess_prefix: %s",err->message);
   22.14      g_assert(err == NULL);
   22.15 -    default_prefix=plover_default_prefix_for_vendor("Acme Corporation");
   22.16 +    comps=plover_comps_new();
   22.17 +    plover_comps_set_vendor(comps,"Acme Corporation");
   22.18 +    default_prefix=plover_comps_get_default_prefix(comps);
   22.19 +    plover_comps_free(comps);
   22.20      g_assert_cmpstr(prefix,==,default_prefix);
   22.21      g_free(default_prefix);
   22.22  }
   22.23 @@ -164,23 +168,29 @@
   22.24  
   22.25  static void verify_zappy_set(PloverPackageSet *package_set)
   22.26  {
   22.27 +    char *root_uri;
   22.28      verify_package_set(package_set,G_N_ELEMENTS(zappy_packages),zappy_packages,
   22.29        NULL);
   22.30 +    root_uri=razor_path_to_uri("../razor-test-dir");
   22.31      g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,
   22.32 -      "../razor-test-dir");
   22.33 +      root_uri);
   22.34 +    free(root_uri);
   22.35  }
   22.36  
   22.37  static void test_open(void)
   22.38  {
   22.39 +    char *root_uri;
   22.40      PloverPackageSet *package_set;
   22.41      GError *err=NULL;
   22.42      package_set=plover_package_set_new();
   22.43      g_assert(PLOVER_IS_PACKAGE_SET(package_set));
   22.44 -    if (!plover_package_set_open(package_set,"../razor-test-dir",FALSE,&err))
   22.45 +    root_uri=razor_path_to_uri("../razor-test-dir");
   22.46 +    if (!plover_package_set_open(package_set,root_uri,FALSE,&err))
   22.47      {
   22.48  	g_assert(err && err->message);
   22.49  	g_error("../razor-test-dir: %s",err->message);
   22.50      }
   22.51 +    free(root_uri);
   22.52      g_assert(!err);
   22.53      verify_zappy_set(package_set);
   22.54      plover_package_set_close(package_set);
   22.55 @@ -195,17 +205,20 @@
   22.56      struct razor_package *pkg;
   22.57      struct razor_package_iterator *iter;
   22.58      struct razor_atomic *atomic;
   22.59 +    struct comps *comps;
   22.60      PloverPackageSet *package_set;
   22.61      PloverPackage *package;
   22.62      GError *err=NULL;
   22.63      const char *prefix;
   22.64 -    gchar *root;
   22.65 +    char root[]="razor-test-dir-XXXXXX";
   22.66 +    char *root_uri;
   22.67 +    gchar *default_prefix;
   22.68      GSList *packages;
   22.69      package_set=plover_package_set_new();
   22.70      g_assert(PLOVER_IS_PACKAGE_SET(package_set));
   22.71 -    root=g_strdup("razor-test-dir-XXXXXX");
   22.72      g_assert(mkdtemp(root));
   22.73 -    if (!plover_package_set_open(package_set,root,TRUE,&err))
   22.74 +    root_uri=razor_path_to_uri(root);
   22.75 +    if (!plover_package_set_open(package_set,root_uri,TRUE,&err))
   22.76      {
   22.77  	g_assert(err && err->message);
   22.78  	g_error("%s: %s",root,err->message);
   22.79 @@ -216,8 +229,9 @@
   22.80      g_assert(plover_package_set_set_header_version(package_set,
   22.81        RAZOR_HEADER_VERSION_MIN));
   22.82      g_assert(plover_package_set_set_header_version(package_set,ver));
   22.83 -    g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,root);
   22.84 -    g_free(root);
   22.85 +    g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,
   22.86 +      root_uri);
   22.87 +    free(root_uri);
   22.88      g_assert(plover_package_set_get_exclusive(package_set));
   22.89      set=plover_package_set_get_razor(package_set);
   22.90      g_assert(set != NULL);
   22.91 @@ -246,8 +260,12 @@
   22.92      if (!prefix && err)
   22.93  	g_error("plover_package_set_guess_prefix: %s",err->message);
   22.94      g_assert(err == NULL);
   22.95 -    g_assert_cmpstr(prefix,==,
   22.96 -      plover_default_prefix_for_vendor("Acme Corporation"));
   22.97 +    comps=plover_comps_new();
   22.98 +    plover_comps_set_vendor(comps,"Acme Corporation");
   22.99 +    default_prefix=plover_comps_get_default_prefix(comps);
  22.100 +    plover_comps_free(comps);
  22.101 +    g_assert_cmpstr(prefix,==,default_prefix);
  22.102 +    g_free(default_prefix);
  22.103      plover_package_set_close(package_set);
  22.104      g_object_unref(package_set);
  22.105  }
  22.106 @@ -257,7 +275,10 @@
  22.107      PloverPackageSet *package_set;
  22.108      PloverPackage *package;
  22.109      GError *err=NULL;
  22.110 -    package_set=plover_package_set_new_from_installed("../razor-test-dir",&err);
  22.111 +    char *root_uri;
  22.112 +    root_uri=razor_path_to_uri("../razor-test-dir");
  22.113 +    package_set=plover_package_set_new_from_installed(root_uri,&err);
  22.114 +    free(root_uri);
  22.115      if (!package_set && err)
  22.116  	g_error("../razor-test-dir: %s",err->message);
  22.117      g_assert(PLOVER_IS_PACKAGE_SET(package_set));
    23.1 --- a/tests/plover/test-transaction.c	Fri Jul 08 08:33:44 2016 +0100
    23.2 +++ b/tests/plover/test-transaction.c	Sat Jul 16 11:07:18 2016 +0100
    23.3 @@ -56,14 +56,11 @@
    23.4      struct razor_package *pkg;
    23.5      enum razor_install_action action;
    23.6      int count;
    23.7 -    gchar *root_uri;
    23.8 +    char *root_uri;
    23.9      GError *err=NULL;
   23.10 -    GFile *file;
   23.11 -    file=g_file_new_for_path("../razor-test-dir");
   23.12 -    root_uri=g_file_get_uri(file);
   23.13 -    g_object_unref(file);
   23.14 +    root_uri=razor_path_to_uri("../razor-test-dir");
   23.15      g_setenv("RAZOR_ROOT",root_uri,TRUE);
   23.16 -    g_free(root_uri);
   23.17 +    free(root_uri);
   23.18      transaction=plover_transaction_new_update("../yum-repo-test-dir","/test",
   23.19        NULL,&err);
   23.20      if (!transaction && err)
   23.21 @@ -215,7 +212,6 @@
   23.22      g_assert_cmpstr(name,==,"uninstallable");
   23.23      g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count));
   23.24      g_assert(!plover_transaction_commit(transaction,NULL,&err));
   23.25 -    g_message("plover_transaction_commit: %s",err->message);
   23.26      g_assert_cmpint(err->domain,==,PLOVER_RAZOR_ERROR);
   23.27      g_assert_cmpint(err->code,==,RAZOR_GENERAL_ERROR_FAILED);
   23.28      g_clear_error(&err);
    24.1 --- a/tests/plover/test-uri-handler.c	Fri Jul 08 08:33:44 2016 +0100
    24.2 +++ b/tests/plover/test-uri-handler.c	Sat Jul 16 11:07:18 2016 +0100
    24.3 @@ -47,13 +47,13 @@
    24.4      g_setenv("RAZOR_ROOT",root_uri,TRUE);
    24.5      g_free(root_uri);
    24.6      comps=plover_comps_new_from_uri(
    24.7 -      "resource:///uk/co/juiblex/project/plover/repodata/comps.xml");
    24.8 +      "resource:///uk/co/juiblex/project/plover/repodata/comps.xml",&error);
    24.9      if (!comps)
   24.10      {
   24.11 -	perror("resource:///uk/co/juiblex/project/plover/repodata/comps.xml");
   24.12 +	fprintf(stderr,"%s\n",error->message);
   24.13  	exit(1);
   24.14      }
   24.15 -    prefix=plover_default_prefix_for_vendor(comps->vendor);
   24.16 +    prefix=plover_comps_get_default_prefix(comps);
   24.17      group=plover_comps_lookup_group(comps,"base");
   24.18      if (!group)
   24.19      {
    25.1 --- a/update/Makefile.am	Fri Jul 08 08:33:44 2016 +0100
    25.2 +++ b/update/Makefile.am	Sat Jul 16 11:07:18 2016 +0100
    25.3 @@ -3,28 +3,20 @@
    25.4  INCLUDES=-I$(top_srcdir)
    25.5  CCLD = $(CXX)
    25.6  
    25.7 -bin_PROGRAMS=update updatez
    25.8 +bin_PROGRAMS=update
    25.9  bin_SCRIPTS=update.js
   25.10  
   25.11  update_SOURCES=update.c
   25.12  update_LDFLAGS=-all-static
   25.13  update_LIBTOOLFLAGS=--tag=CXX
   25.14  if HAVE_WINDRES
   25.15 -update_SOURCES+=update-res.rc update.exe.manifest
   25.16 -endif
   25.17 -
   25.18 -updatez_SOURCES=updatez.c
   25.19 -updatez_LDFLAGS=-all-static
   25.20 -updatez_LIBTOOLFLAGS=--tag=CXX
   25.21 -if HAVE_WINDRES
   25.22 -updatez_SOURCES+=updatez-res.rc updatez.exe.manifest
   25.23 +update_SOURCES+=resources.rc update.exe.manifest
   25.24  endif
   25.25  
   25.26  .rc.$(OBJEXT):
   25.27  	$(AM_V_GEN)$(WINDRES) $< $@
   25.28  
   25.29 -update-res.$(OBJEXT): update-res.rc update.exe.manifest update.ico
   25.30 -updatez-res.$(OBJEXT): updatez-res.rc updatez.exe.manifest update.ico
   25.31 +resources.$(OBJEXT): resources.rc update.exe.manifest update.ico
   25.32  
   25.33  %.js: $(srcdir)/%.js.in
   25.34  	$(AM_V_GEN)sed -e 's/$$/\r/' $(srcdir)/$@.in > $@
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/update/manifest.xml.in	Sat Jul 16 11:07:18 2016 +0100
    26.3 @@ -0,0 +1,22 @@
    26.4 +changequote([,])dnl
    26.5 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    26.6 +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    26.7 +  <assemblyIdentity
    26.8 +    version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
    26.9 +    name="The plover development team.plover.update" type="win32"
   26.10 +    processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
   26.11 +  <description>Plover update program</description>
   26.12 +  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
   26.13 +    <application>
   26.14 +      <!-- Windows 7 functionality -->
   26.15 +      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   26.16 +    </application>
   26.17 +  </compatibility>
   26.18 +  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   26.19 +    <security>
   26.20 +      <requestedPrivileges>
   26.21 +        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
   26.22 +      </requestedPrivileges>
   26.23 +    </security>
   26.24 +  </trustInfo>
   26.25 +</assembly>
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/update/resources.rc.in	Sat Jul 16 11:07:18 2016 +0100
    27.3 @@ -0,0 +1,37 @@
    27.4 +#include <winver.h>
    27.5 +#include <winuser.h>
    27.6 +
    27.7 +#pragma code_page(65001)
    27.8 +
    27.9 +MAINICON ICON "update.ico"
   27.10 +
   27.11 +VS_VERSION_INFO VERSIONINFO
   27.12 +    FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
   27.13 +      @PLOVER_MICRO_VERSION@,0
   27.14 +    PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
   27.15 +      @PLOVER_MICRO_VERSION@,0
   27.16 +    FILEOS VOS__WINDOWS32
   27.17 +    FILETYPE VFT_APP
   27.18 +    {
   27.19 +	BLOCK "StringFileInfo"
   27.20 +	{
   27.21 +	    BLOCK "080904B0"
   27.22 +	    {
   27.23 +		VALUE "CompanyName","The plover development team"
   27.24 +		VALUE "FileDescription","Plover update program"
   27.25 +		VALUE "FileVersion","@PACKAGE_VERSION@"
   27.26 +		VALUE "InternalName","update"
   27.27 +		VALUE "LegalCopyright",
   27.28 +		  "Copyright © 2009,2011,2012 J. Ali Harlow et al"
   27.29 +		VALUE "OriginalFilename","update.exe"
   27.30 +		VALUE "ProductName","plover"
   27.31 +		VALUE "ProductVersion","@PACKAGE_VERSION@"
   27.32 +	    }
   27.33 +	}
   27.34 +	BLOCK "VarFileInfo"
   27.35 +	{
   27.36 +	    VALUE "Translation",0x809,0x4B0
   27.37 +	}
   27.38 +    }
   27.39 +
   27.40 +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update.exe.manifest"
    28.1 --- a/update/update-res.rc.in	Fri Jul 08 08:33:44 2016 +0100
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,37 +0,0 @@
    28.4 -#include <winver.h>
    28.5 -#include <winuser.h>
    28.6 -
    28.7 -#pragma code_page(65001)
    28.8 -
    28.9 -MAINICON ICON "update.ico"
   28.10 -
   28.11 -VS_VERSION_INFO VERSIONINFO
   28.12 -    FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
   28.13 -      @PLOVER_MICRO_VERSION@,0
   28.14 -    PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
   28.15 -      @PLOVER_MICRO_VERSION@,0
   28.16 -    FILEOS VOS__WINDOWS32
   28.17 -    FILETYPE VFT_APP
   28.18 -    {
   28.19 -	BLOCK "StringFileInfo"
   28.20 -	{
   28.21 -	    BLOCK "080904B0"
   28.22 -	    {
   28.23 -		VALUE "CompanyName","The plover development team"
   28.24 -		VALUE "FileDescription","Plover update program"
   28.25 -		VALUE "FileVersion","@PACKAGE_VERSION@"
   28.26 -		VALUE "InternalName","update"
   28.27 -		VALUE "LegalCopyright",
   28.28 -		  "Copyright © 2009,2011,2012 J. Ali Harlow et al"
   28.29 -		VALUE "OriginalFilename","update.exe"
   28.30 -		VALUE "ProductName","plover"
   28.31 -		VALUE "ProductVersion","@PACKAGE_VERSION@"
   28.32 -	    }
   28.33 -	}
   28.34 -	BLOCK "VarFileInfo"
   28.35 -	{
   28.36 -	    VALUE "Translation",0x809,0x4B0
   28.37 -	}
   28.38 -    }
   28.39 -
   28.40 -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update.exe.manifest"
    29.1 --- a/update/update.c	Fri Jul 08 08:33:44 2016 +0100
    29.2 +++ b/update/update.c	Sat Jul 16 11:07:18 2016 +0100
    29.3 @@ -1,5 +1,5 @@
    29.4  /*
    29.5 - * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
    29.6 + * Copyright (C) 2009, 2011, 2016  J. Ali Harlow <ali@juiblex.co.uk>
    29.7   *
    29.8   * This program is free software; you can redistribute it and/or modify
    29.9   * it under the terms of the GNU General Public License as published by
   29.10 @@ -18,6 +18,7 @@
   29.11  
   29.12  #include <stdlib.h>
   29.13  #include <stdio.h>
   29.14 +#include <errno.h>
   29.15  #include <lua.h>
   29.16  #include "config.h"
   29.17  #include "plover/plover.h"
   29.18 @@ -27,22 +28,85 @@
   29.19  
   29.20  void update(const char *argv0)
   29.21  {
   29.22 -    char *path;
   29.23 -    gchar *s,*prefix;
   29.24 +    char *yum_uri,*local_database,*active_database,*alternate_database;
   29.25 +    gchar *s,*prefix,*distribution,*vendor_prefix;
   29.26      int ch;
   29.27      struct comps *comps;
   29.28      GError *error=NULL;
   29.29 -    path=plover_get_program_directory(argv0);
   29.30 -    s=g_strconcat(path,"/repodata/comps.xml",NULL);
   29.31 -    comps=plover_comps_new_from_file(s);
   29.32 +    s=plover_get_program(argv0);
   29.33 +    yum_uri=razor_path_to_uri(s);
   29.34 +    g_free(s);
   29.35 +    s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL);
   29.36 +    comps=plover_comps_new_from_uri(s,&error);
   29.37 +    g_free(s);
   29.38 +    if (g_error_matches(error,PLOVER_RAZOR_ERROR,
   29.39 +      RAZOR_GENERAL_ERROR_UNSUPPORTED_ARCHIVE))
   29.40 +    {
   29.41 +	g_clear_error(&error);
   29.42 +	free(yum_uri);
   29.43 +	s=plover_get_program_directory(argv0);
   29.44 +	yum_uri=razor_path_to_uri(s);
   29.45 +	g_free(s);
   29.46 +	s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL);
   29.47 +	comps=plover_comps_new_from_uri(s,&error);
   29.48 +    }
   29.49      if (!comps)
   29.50      {
   29.51 -	perror(s);
   29.52 +	fprintf(stderr,"%s\n",error->message);
   29.53 +	g_error_free(error);
   29.54  	exit(1);
   29.55      }
   29.56 -    g_free(s);
   29.57 -    prefix=plover_default_prefix_for_vendor(comps->vendor);
   29.58 -    if (!plover_installed_files_match_prefix(prefix))
   29.59 +    prefix=plover_comps_get_default_prefix(comps);
   29.60 +    if (prefix)
   29.61 +    {
   29.62 +	s=g_strconcat(prefix,"/var/lib/razor",NULL);
   29.63 +	local_database=razor_path_to_uri(s);
   29.64 +	g_free(s);
   29.65 +    }
   29.66 +    else
   29.67 +	local_database=NULL;
   29.68 +    switch(comps->database)
   29.69 +    {
   29.70 +	case COMPS_DATABASE_DISTRIBUTION_LOCAL:
   29.71 +	    active_database=local_database;
   29.72 +	    alternate_database=NULL;
   29.73 +	    break;
   29.74 +	case COMPS_DATABASE_GLOBAL:
   29.75 +	    active_database=NULL;
   29.76 +	    alternate_database=local_database;
   29.77 +	    break;
   29.78 +    }
   29.79 +    if (prefix)
   29.80 +    {
   29.81 +	distribution=g_strdup(comps->distribution);
   29.82 +	plover_comps_set_distribution(comps,NULL);
   29.83 +	vendor_prefix=plover_comps_get_default_prefix(comps);
   29.84 +	plover_comps_set_distribution(comps,distribution);
   29.85 +	g_free(distribution);
   29.86 +	razor_set_database_uri(alternate_database);
   29.87 +	if (plover_installed_files_match_prefix(vendor_prefix)==1)
   29.88 +	{
   29.89 +	    printf("There is an existing installation under %s\n"
   29.90 +	      "which is not compatible with this distribution. In order\n"
   29.91 +	      "to continue, the existing installation must be uninstalled.\n"
   29.92 +	      "Do you want to remove all packages in the existing installion? ",
   29.93 +	      prefix);
   29.94 +	    ch=getchar();
   29.95 +	    if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n')
   29.96 +		exit(1);
   29.97 +	    while(ch!='\n' && ch!=EOF)
   29.98 +		ch=getchar();
   29.99 +	    if (plover_remove(NULL,&error))
  29.100 +	    {
  29.101 +		fprintf(stderr,"%s\n",error->message);
  29.102 +		g_error_free(error);
  29.103 +		exit(1);
  29.104 +	    }
  29.105 +	}
  29.106 +	g_free(vendor_prefix);
  29.107 +    }
  29.108 +    razor_set_database_uri(active_database);
  29.109 +    if (prefix && !plover_installed_files_match_prefix(prefix))
  29.110      {
  29.111  	printf("The existing installation is not under %s\n"
  29.112  	  "In order to continue, all the existing packages must be removed.\n"
  29.113 @@ -59,15 +123,16 @@
  29.114  	    exit(1);
  29.115  	}
  29.116      }
  29.117 +    free(local_database);
  29.118      plover_comps_free(comps);
  29.119 -    if (!plover_update(path,prefix,NULL,&error))
  29.120 +    if (!plover_update_uri(yum_uri,prefix,NULL,&error))
  29.121      {
  29.122  	fprintf(stderr,"%s\n",error->message);
  29.123  	g_error_free(error);
  29.124  	exit(1);
  29.125      }
  29.126      g_free(prefix);
  29.127 -    free(path);
  29.128 +    free(yum_uri);
  29.129  }
  29.130  
  29.131  int main(int argc,char **argv)
    30.1 --- a/update/update.manifest.in	Fri Jul 08 08:33:44 2016 +0100
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,22 +0,0 @@
    30.4 -changequote([,])dnl
    30.5 -<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    30.6 -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    30.7 -  <assemblyIdentity
    30.8 -    version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
    30.9 -    name="The plover development team.plover.update" type="win32"
   30.10 -    processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
   30.11 -  <description>Plover update program</description>
   30.12 -  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
   30.13 -    <application>
   30.14 -      <!-- Windows 7 functionality -->
   30.15 -      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   30.16 -    </application>
   30.17 -  </compatibility>
   30.18 -  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   30.19 -    <security>
   30.20 -      <requestedPrivileges>
   30.21 -        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
   30.22 -      </requestedPrivileges>
   30.23 -    </security>
   30.24 -  </trustInfo>
   30.25 -</assembly>
    31.1 --- a/update/updatez-res.rc.in	Fri Jul 08 08:33:44 2016 +0100
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,37 +0,0 @@
    31.4 -#include <winver.h>
    31.5 -#include <winuser.h>
    31.6 -
    31.7 -#pragma code_page(65001)
    31.8 -
    31.9 -MAINICON ICON "update.ico"
   31.10 -
   31.11 -VS_VERSION_INFO VERSIONINFO
   31.12 -    FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
   31.13 -      @PLOVER_MICRO_VERSION@,0
   31.14 -    PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
   31.15 -      @PLOVER_MICRO_VERSION@,0
   31.16 -    FILEOS VOS__WINDOWS32
   31.17 -    FILETYPE VFT_APP
   31.18 -    {
   31.19 -	BLOCK "StringFileInfo"
   31.20 -	{
   31.21 -	    BLOCK "080904B0"
   31.22 -	    {
   31.23 -		VALUE "CompanyName","The plover development team"
   31.24 -		VALUE "FileDescription","Plover update program"
   31.25 -		VALUE "FileVersion","@PACKAGE_VERSION@"
   31.26 -		VALUE "InternalName","updatez"
   31.27 -		VALUE "LegalCopyright",
   31.28 -		  "Copyright © 2009,2011,2012 J. Ali Harlow et al"
   31.29 -		VALUE "OriginalFilename","updatez.exe"
   31.30 -		VALUE "ProductName","plover"
   31.31 -		VALUE "ProductVersion","@PACKAGE_VERSION@"
   31.32 -	    }
   31.33 -	}
   31.34 -	BLOCK "VarFileInfo"
   31.35 -	{
   31.36 -	    VALUE "Translation",0x809,0x4B0
   31.37 -	}
   31.38 -    }
   31.39 -
   31.40 -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "updatez.exe.manifest"
    32.1 --- a/update/updatez.c	Fri Jul 08 08:33:44 2016 +0100
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,82 +0,0 @@
    32.4 -/*
    32.5 - * Copyright (C) 2009, 2011, 2016  J. Ali Harlow <ali@juiblex.co.uk>
    32.6 - *
    32.7 - * This program is free software; you can redistribute it and/or modify
    32.8 - * it under the terms of the GNU General Public License as published by
    32.9 - * the Free Software Foundation; either version 2 of the License, or
   32.10 - * (at your option) any later version.
   32.11 - *
   32.12 - * This program is distributed in the hope that it will be useful,
   32.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.15 - * GNU General Public License for more details.
   32.16 - *
   32.17 - * You should have received a copy of the GNU General Public License along
   32.18 - * with this program; if not, write to the Free Software Foundation, Inc.,
   32.19 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   32.20 - */
   32.21 -
   32.22 -#include <stdlib.h>
   32.23 -#include <stdio.h>
   32.24 -#include <lua.h>
   32.25 -#include "config.h"
   32.26 -#include "plover/plover.h"
   32.27 -#include "whelk/whelk.h"
   32.28 -
   32.29 -LUALIB_API int luaopen_posix(lua_State *L);
   32.30 -
   32.31 -void update_from_executable_zip(const char *argv0)
   32.32 -{
   32.33 -    char *uri;
   32.34 -    gchar *s,*prefix;
   32.35 -    int ch;
   32.36 -    struct comps *comps;
   32.37 -    GError *error=NULL;
   32.38 -    s=plover_get_program(argv0);
   32.39 -    uri=g_strconcat("file:",s,NULL);
   32.40 -    g_free(s);
   32.41 -    s=g_strconcat(uri,"/repodata/comps.xml",NULL);
   32.42 -    comps=plover_comps_new_from_uri(s);
   32.43 -    if (!comps)
   32.44 -    {
   32.45 -	perror(s);
   32.46 -	exit(1);
   32.47 -    }
   32.48 -    g_free(s);
   32.49 -    prefix=plover_default_prefix_for_vendor(comps->vendor);
   32.50 -    if (!plover_installed_files_match_prefix(prefix))
   32.51 -    {
   32.52 -	printf("The existing installation is not under %s\n"
   32.53 -	  "In order to continue, all the existing packages must be removed.\n"
   32.54 -	  "Do you want to remove all existing packages? ",prefix);
   32.55 -	ch=getchar();
   32.56 -	if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n')
   32.57 -	    exit(1);
   32.58 -	while(ch!='\n' && ch!=EOF)
   32.59 -	    ch=getchar();
   32.60 -	if (plover_remove(NULL,&error))
   32.61 -	{
   32.62 -	    fprintf(stderr,"%s\n",error->message);
   32.63 -	    g_error_free(error);
   32.64 -	    exit(1);
   32.65 -	}
   32.66 -    }
   32.67 -    plover_comps_free(comps);
   32.68 -    if (!plover_update_uri(uri,prefix,NULL,&error))
   32.69 -    {
   32.70 -	fprintf(stderr,"%s\n",error->message);
   32.71 -	g_error_free(error);
   32.72 -	exit(1);
   32.73 -    }
   32.74 -    g_free(prefix);
   32.75 -    free(uri);
   32.76 -}
   32.77 -
   32.78 -int main(int argc,char **argv)
   32.79 -{
   32.80 -    plover_exception_handler_init();
   32.81 -    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
   32.82 -    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
   32.83 -    update_from_executable_zip(argv[0]);
   32.84 -    exit(0);
   32.85 -}
    33.1 --- a/update/updatez.manifest.in	Fri Jul 08 08:33:44 2016 +0100
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,22 +0,0 @@
    33.4 -changequote([,])dnl
    33.5 -<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    33.6 -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    33.7 -  <assemblyIdentity
    33.8 -    version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
    33.9 -    name="The plover development team.plover.updatez" type="win32"
   33.10 -    processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
   33.11 -  <description>Plover update program</description>
   33.12 -  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
   33.13 -    <application>
   33.14 -      <!-- Windows 7 functionality -->
   33.15 -      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   33.16 -    </application>
   33.17 -  </compatibility>
   33.18 -  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   33.19 -    <security>
   33.20 -      <requestedPrivileges>
   33.21 -        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
   33.22 -      </requestedPrivileges>
   33.23 -    </security>
   33.24 -  </trustInfo>
   33.25 -</assembly>