Support razor 0.5 (atomic transactions).
authorJ. Ali Harlow <ali@juiblex.co.uk>
Thu Nov 10 11:15:09 2011 +0000 (2011-11-10)
changeset 13b0a35bae4961
parent 12 1d18b9c34d26
child 14 29d8bb64056c
Support razor 0.5 (atomic transactions).
Don't create repositories with multiple roots.
Filter out "other" arches from yum repositories.
Mark win32 binaries as needing elevated privileges.
acinclude.m4
app-manager/Makefile.am
app-manager/manifest.xml.in
app-manager/resources.rc.in
configure.ac
plover-gtk/error.h
plover-gtk/packageset.c
plover/import-yum.c
plover/plover.h
plover/razor.c
plover/util.c
setup/Makefile.am
setup/manifest.xml.in
setup/resources.rc.in
setup/setup.c
update/Makefile.am
update/manifest.xml.in
update/resources.rc.in
update/update.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/acinclude.m4	Thu Nov 10 11:15:09 2011 +0000
     1.3 @@ -0,0 +1,8 @@
     1.4 +# Usage:
     1.5 +#	PLOVER_MSWIN_MANIFEST([output],[input])
     1.6 +AC_DEFUN([PLOVER_MSWIN_MANIFEST],[m4_foreach_w([PLOVER_File],[$1],
     1.7 +    [m4_define([PLOVER_Output],m4_bpatsubst(PLOVER_File,[:.*],[]))
     1.8 +      AC_CONFIG_FILES(PLOVER_File,
     1.9 +      [m4] PLOVER_Output [>] PLOVER_Output[.new;]
    1.10 +      [mv] PLOVER_Output[.new] PLOVER_Output
    1.11 +      )])])
     2.1 --- a/app-manager/Makefile.am	Thu Nov 10 11:00:49 2011 +0000
     2.2 +++ b/app-manager/Makefile.am	Thu Nov 10 11:15:09 2011 +0000
     2.3 @@ -5,7 +5,7 @@
     2.4  app_manager_SOURCES=app-manager.c app-manager.h packagelist.c applications.c \
     2.5  	localmedia.c localmedia.h
     2.6  if HAVE_WINDRES
     2.7 -app_manager_SOURCES+=resources.rc
     2.8 +app_manager_SOURCES+=resources.rc app-manager.exe.manifest
     2.9  endif
    2.10  uidir=$(pkgdatadir)
    2.11  ui_DATA=app-manager.ui
    2.12 @@ -21,7 +21,7 @@
    2.13  .rc.$(OBJEXT):
    2.14  	$(WINDRES) $< $@
    2.15  
    2.16 -resources.$(OBJEXT):	app-manager.ico
    2.17 +resources.$(OBJEXT):	app-manager.ico app-manager.exe.manifest
    2.18  
    2.19  plover-applications%.pnm:	plover-applications.svg
    2.20  	rsvg -w $* -h $* -f png $< temp.png
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/app-manager/manifest.xml.in	Thu Nov 10 11:15:09 2011 +0000
     3.3 @@ -0,0 +1,22 @@
     3.4 +changequote([,])dnl
     3.5 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     3.6 +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
     3.7 +  <assemblyIdentity
     3.8 +    version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
     3.9 +    name="The plover development team.plover.app-manager" type="win32"
    3.10 +    processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
    3.11 +  <description>Application Manager</description>
    3.12 +  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    3.13 +    <application>
    3.14 +      <!-- Windows 7 functionality -->
    3.15 +      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
    3.16 +    </application>
    3.17 +  </compatibility>
    3.18 +  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    3.19 +    <security>
    3.20 +      <requestedPrivileges>
    3.21 +        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
    3.22 +      </requestedPrivileges>
    3.23 +    </security>
    3.24 +  </trustInfo>
    3.25 +</assembly>
     4.1 --- a/app-manager/resources.rc.in	Thu Nov 10 11:00:49 2011 +0000
     4.2 +++ b/app-manager/resources.rc.in	Thu Nov 10 11:15:09 2011 +0000
     4.3 @@ -1,4 +1,5 @@
     4.4  #include <winver.h>
     4.5 +#include <winuser.h>
     4.6  
     4.7  MAINICON ICON "app-manager.ico"
     4.8  
     5.1 --- a/configure.ac	Thu Nov 10 11:00:49 2011 +0000
     5.2 +++ b/configure.ac	Thu Nov 10 11:15:09 2011 +0000
     5.3 @@ -1,7 +1,7 @@
     5.4  #                                               -*- Autoconf -*-
     5.5  # Process this file with autoconf to produce a configure script.
     5.6  
     5.7 -AC_INIT([plover],[0.3],[ali@juiblex.co.uk])
     5.8 +AC_INIT([plover],[0.4],[ali@juiblex.co.uk])
     5.9  AC_PREREQ(2.59)
    5.10  AC_CONFIG_AUX_DIR([config])
    5.11  AC_CONFIG_SRCDIR([plover/plover.h])
    5.12 @@ -18,6 +18,10 @@
    5.13  app-manager/Makefile
    5.14  app-manager/resources.rc
    5.15  ])
    5.16 +PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in
    5.17 +update/update.exe.manifest:update/manifest.xml.in
    5.18 +app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in
    5.19 +])
    5.20  AM_INIT_AUTOMAKE(no-define)
    5.21  case $VERSION in
    5.22    *.*.*)
    5.23 @@ -37,6 +41,9 @@
    5.24      AC_SUBST(PLOVER_MICRO_VERSION,0)
    5.25      ;;
    5.26  esac
    5.27 +AC_CANONICAL_HOST
    5.28 +AC_SUBST(HOST_OS,$host_os)
    5.29 +AC_SUBST(HOST_CPU,$host_cpu)
    5.30  
    5.31  # libtool versioning for libplover. For a release one of the following
    5.32  # must apply:
    5.33 @@ -47,8 +54,8 @@
    5.34  #   increment CURRENT and set AGE and REVISION to 0.
    5.35  # - If the interface is the same as the previous version, increment REVISION.
    5.36  #
    5.37 -lt_current=0
    5.38 -lt_revision=1
    5.39 +lt_current=1
    5.40 +lt_revision=0
    5.41  lt_age=0
    5.42  LIBPLOVER_LT_VERSION_INFO="$lt_current:$lt_revision:$lt_age"
    5.43  AC_SUBST(LIBPLOVER_LT_VERSION_INFO)
    5.44 @@ -56,7 +63,7 @@
    5.45  # and likewise for plover-gtk.
    5.46  #
    5.47  lt_current=0
    5.48 -lt_revision=0
    5.49 +lt_revision=1
    5.50  lt_age=0
    5.51  PLOVER_GTK_LT_VERSION_INFO="$lt_current:$lt_revision:$lt_age"
    5.52  AC_SUBST(PLOVER_GTK_LT_VERSION_INFO)
    5.53 @@ -75,6 +82,9 @@
    5.54  # Checks for header files.
    5.55  ##################################################
    5.56  AC_HEADER_STDC
    5.57 +AC_CHECK_HEADERS([winhttp.h],[],[],
    5.58 +[#include <windows.h>
    5.59 +])
    5.60  
    5.61  ##################################################
    5.62  # Checks for typedefs, structures, and compiler characteristics.
    5.63 @@ -83,7 +93,7 @@
    5.64  ##################################################
    5.65  # Checks for libraries.
    5.66  ##################################################
    5.67 -PKG_CHECK_MODULES(RAZOR,[razor >= 0.2],[:],[RAZOR_LIBS=-lrazor])
    5.68 +PKG_CHECK_MODULES(RAZOR,[razor >= 0.5],[:],[RAZOR_LIBS=-lrazor])
    5.69  PKG_CHECK_MODULES(EXPAT,[expat],[:],[EXPAT_LIBS=-lexpat])
    5.70  PKG_CHECK_MODULES(ZLIB,[zlib],[:],[ZLIB_LIBS=-lz])
    5.71  PKG_CHECK_MODULES(GIO,[gio-2.0])
     6.1 --- a/plover-gtk/error.h	Thu Nov 10 11:00:49 2011 +0000
     6.2 +++ b/plover-gtk/error.h	Thu Nov 10 11:15:09 2011 +0000
     6.3 @@ -7,5 +7,6 @@
     6.4      PLOVER_RAZOR_ERROR_FAILED
     6.5  } PloverRazorError;
     6.6  
     6.7 +GQuark plover_razor_error_quark(void);
     6.8 +
     6.9  #endif /* __PLOVER_ERROR_H__ */
    6.10 -
     7.1 --- a/plover-gtk/packageset.c	Thu Nov 10 11:00:49 2011 +0000
     7.2 +++ b/plover-gtk/packageset.c	Thu Nov 10 11:15:09 2011 +0000
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (C) 2010  J. Ali Harlow <ali@juiblex.co.uk>
     7.6 + * Copyright (C) 2010, 2011  J. Ali Harlow <ali@juiblex.co.uk>
     7.7   *
     7.8   * This program is free software; you can redistribute it and/or modify
     7.9   * it under the terms of the GNU General Public License as published by
    7.10 @@ -21,6 +21,7 @@
    7.11  #include <string.h>
    7.12  #include <fcntl.h>
    7.13  #include <errno.h>
    7.14 +#include <unistd.h>
    7.15  #include <glib-object.h>
    7.16  #include <razor.h>
    7.17  #include "plover/plover.h"
    7.18 @@ -31,6 +32,7 @@
    7.19  G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT);
    7.20  
    7.21  typedef struct _PloverPackageSetPrivate {
    7.22 +    struct razor_atomic *atomic;
    7.23      struct razor_root *root;
    7.24      struct razor_set *set;
    7.25      GSList *packages;
    7.26 @@ -53,14 +55,9 @@
    7.27  {
    7.28      PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
    7.29      if (priv->root)
    7.30 -    {
    7.31 -	/* priv->set, if set, is owned by priv->root and should not
    7.32 -	 * be destroyed.
    7.33 -	 */
    7.34  	razor_root_close(priv->root);
    7.35 -    }
    7.36 -    else if (priv->set)
    7.37 -	razor_set_destroy(priv->set);
    7.38 +    if (priv->atomic)
    7.39 +	razor_atomic_destroy(priv->atomic);
    7.40      if (G_OBJECT_CLASS(plover_package_set_parent_class)->finalize)
    7.41  	G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj);
    7.42  }
    7.43 @@ -68,6 +65,11 @@
    7.44  static void plover_package_set_dispose(GObject *obj)
    7.45  {
    7.46      PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
    7.47 +    if (priv->set)
    7.48 +    {
    7.49 +	razor_set_unref(priv->set);
    7.50 +	priv->set=NULL;
    7.51 +    }
    7.52      if (G_OBJECT_CLASS(plover_package_set_parent_class)->dispose)
    7.53  	G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj);
    7.54  }
    7.55 @@ -102,7 +104,8 @@
    7.56      PloverPackageSetPrivate *priv;
    7.57      set=plover_package_set_new();
    7.58      priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
    7.59 -    priv->root=razor_root_open(root);
    7.60 +    priv->atomic=razor_atomic_open("Read root package set");
    7.61 +    priv->root=razor_root_open(root,priv->atomic);
    7.62      if (!priv->root)
    7.63      {
    7.64  	g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
    7.65 @@ -110,7 +113,7 @@
    7.66  	g_object_unref(set);
    7.67  	return NULL;
    7.68      }
    7.69 -    priv->set=razor_root_get_system_set(priv->root);
    7.70 +    priv->set=razor_set_ref(razor_root_get_system_set(priv->root));
    7.71      if (!priv->set)
    7.72      {
    7.73  	g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
    7.74 @@ -132,6 +135,7 @@
    7.75  #endif
    7.76      gchar *s;
    7.77      struct razor_set *reloc;
    7.78 +    struct razor_atomic *atomic;
    7.79      PloverPackageSet *set;
    7.80      PloverPackageSetPrivate *priv;
    7.81      set=plover_package_set_new();
    7.82 @@ -164,7 +168,7 @@
    7.83      g_free(s);
    7.84      priv->set=plover_razor_set_create_from_yum("..");
    7.85  #if HAVE_FCHDIR
    7.86 -    fchdir(fd);
    7.87 +    (void)fchdir(fd);
    7.88      close(fd);
    7.89  #else
    7.90      chdir(wd);
    7.91 @@ -172,8 +176,18 @@
    7.92  #endif
    7.93      if (priv->set && relocations)
    7.94      {
    7.95 -	reloc=plover_relocate_packages(priv->set,base,relocations);
    7.96 -	razor_set_destroy(priv->set);
    7.97 +	atomic=razor_atomic_open("Relocate packages");
    7.98 +	reloc=plover_relocate_packages(priv->set,atomic,base,relocations);
    7.99 +	if (!reloc)
   7.100 +	    g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
   7.101 +	      razor_atomic_get_error_msg(atomic));
   7.102 +	razor_atomic_destroy(atomic);
   7.103 +	if (!reloc)
   7.104 +	{
   7.105 +	    g_object_unref(set);
   7.106 +	    return NULL;
   7.107 +	}
   7.108 +	razor_set_unref(priv->set);
   7.109  	priv->set=reloc;
   7.110      }
   7.111      if (!priv->set)
     8.1 --- a/plover/import-yum.c	Thu Nov 10 11:00:49 2011 +0000
     8.2 +++ b/plover/import-yum.c	Thu Nov 10 11:15:09 2011 +0000
     8.3 @@ -1,7 +1,7 @@
     8.4  /*
     8.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     8.6   * Copyright (C) 2008  Red Hat, Inc
     8.7 - * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
     8.8 + * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
     8.9   *
    8.10   * This program is free software; you can redistribute it and/or modify
    8.11   * it under the terms of the GNU General Public License as published by
    8.12 @@ -48,6 +48,7 @@
    8.13  	YUM_STATE_PROVIDES,
    8.14  	YUM_STATE_OBSOLETES,
    8.15  	YUM_STATE_CONFLICTS,
    8.16 +	YUM_STATE_SKIPPING_PACKAGE,
    8.17  	YUM_STATE_FILE
    8.18  };
    8.19  
    8.20 @@ -93,6 +94,9 @@
    8.21  	uint32_t pre, relation, flags;
    8.22  	int i;
    8.23  
    8.24 +	if (ctx->state == YUM_STATE_SKIPPING_PACKAGE)
    8.25 +		return;
    8.26 +
    8.27  	if (strcmp(name, "metadata") == 0) {
    8.28  		for (i = 0; atts[i]; i += 2) {
    8.29  			if (strcmp(atts[i], "packages") == 0)
    8.30 @@ -126,8 +130,12 @@
    8.31  		}
    8.32  
    8.33  		razor_build_evr(buffer, sizeof buffer, epoch, version, release);
    8.34 -		razor_importer_begin_package(ctx->importer,
    8.35 -					     ctx->name, buffer, ctx->arch);
    8.36 +		if (!strcmp(ctx->arch, "noarch") ||
    8.37 +		    !strcmp(ctx->arch, razor_system_arch())) {
    8.38 +			razor_importer_begin_package(ctx->importer, ctx->name,
    8.39 +						     buffer, ctx->arch);
    8.40 +		} else
    8.41 +			ctx->state = YUM_STATE_SKIPPING_PACKAGE;
    8.42  	} else if (strcmp(name, "summary") == 0) {
    8.43  		ctx->p = ctx->summary;
    8.44  		ctx->state = YUM_STATE_SUMMARY;
    8.45 @@ -213,9 +221,10 @@
    8.46  	}
    8.47  
    8.48  	if (strcmp(name, "package") == 0) {
    8.49 -		razor_importer_add_details(ctx->importer, ctx->summary,
    8.50 -					   ctx->description, ctx->url,
    8.51 -					   ctx->license);
    8.52 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
    8.53 +			razor_importer_add_details(ctx->importer, ctx->summary,
    8.54 +						   ctx->description, ctx->url,
    8.55 +						   ctx->license);
    8.56  
    8.57  		XML_StopParser(ctx->current_parser, XML_TRUE);
    8.58  		ctx->current_parser = ctx->filelists_parser;
    8.59 @@ -250,7 +259,8 @@
    8.60  	const char *pkg, *pkgid;
    8.61  	int i;
    8.62  
    8.63 -	if (strcmp(name, "package") == 0) {
    8.64 +	if (strcmp(name, "package") == 0 &&
    8.65 +	    ctx->state != YUM_STATE_SKIPPING_PACKAGE) {
    8.66  		pkg = NULL;
    8.67  		pkgid = NULL;
    8.68  		for (i = 0; atts[i]; i += 2) {
    8.69 @@ -264,7 +274,8 @@
    8.70  				"mismatch for %s: %s vs %s",
    8.71  				pkg, pkgid, ctx->pkgid);
    8.72  	} else if (strcmp(name, "file") == 0) {
    8.73 -		ctx->state = YUM_STATE_FILE;
    8.74 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
    8.75 +			ctx->state = YUM_STATE_FILE;
    8.76  		ctx->p = ctx->buffer;
    8.77  	}
    8.78  }
    8.79 @@ -274,14 +285,27 @@
    8.80  {
    8.81  	struct yum_context *ctx = data;
    8.82  
    8.83 -	ctx->state = YUM_STATE_BEGIN;
    8.84  	if (strcmp(name, "package") == 0) {
    8.85  		XML_StopParser(ctx->current_parser, XML_TRUE);
    8.86  		ctx->current_parser = ctx->primary_parser;
    8.87 -		razor_importer_finish_package(ctx->importer);
    8.88 -	} else if (strcmp(name, "file") == 0)
    8.89 -		razor_importer_add_file(ctx->importer, ctx->buffer);
    8.90 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
    8.91 +			razor_importer_finish_package(ctx->importer);
    8.92 +		ctx->state = YUM_STATE_BEGIN;
    8.93 +	} else if (strcmp(name, "file") == 0) {
    8.94 +		if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
    8.95 +			razor_importer_add_file(ctx->importer, ctx->buffer);
    8.96 +	}
    8.97 +	if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
    8.98 +		ctx->state = YUM_STATE_BEGIN;
    8.99 +}
   8.100  
   8.101 +static int plover_system_arch_is_x86(void)
   8.102 +{
   8.103 +    const char *arch=razor_system_arch();
   8.104 +    if (!arch || arch[0]!='i' || arch[1]<'3' || arch[1]>'6')
   8.105 +	return 0;
   8.106 +    else
   8.107 +	return !strcmp(arch+2,"86");
   8.108  }
   8.109  
   8.110  #define XML_BUFFER_SIZE 4096
   8.111 @@ -291,9 +315,10 @@
   8.112  {
   8.113  	struct yum_context ctx;
   8.114  	void *buf;
   8.115 -	int len, ret;
   8.116 +	int len;
   8.117  	gzFile primary, filelists;
   8.118  	XML_ParsingStatus status;
   8.119 +	struct razor_set *set;
   8.120  
   8.121  	ctx.importer = razor_importer_create();
   8.122  	ctx.state = YUM_STATE_BEGIN;
   8.123 @@ -329,7 +354,7 @@
   8.124  		XML_GetParsingStatus(ctx.current_parser, &status);
   8.125  		switch (status.parsing) {
   8.126  		case XML_SUSPENDED:
   8.127 -			ret = XML_ResumeParser(ctx.current_parser);
   8.128 +			XML_ResumeParser(ctx.current_parser);
   8.129  			break;
   8.130  		case XML_PARSING:
   8.131  		case XML_INITIALIZED:
   8.132 @@ -360,5 +385,19 @@
   8.133  	gzclose(primary);
   8.134  	gzclose(filelists);
   8.135  
   8.136 -	return razor_importer_finish(ctx.importer);
   8.137 +	set = razor_importer_finish(ctx.importer);
   8.138 +#if RAZOR_HEADER_VERSION_MIN <= 1
   8.139 +	/*
   8.140 +	 * Header version 1 is supported by plover v0.3 and is used on
   8.141 +	 * 32-bit intel machines which allows the setup and update
   8.142 +	 * applications from v0.3 to work. On other machines, we don't
   8.143 +	 * want these old applications to work (since they would do
   8.144 +	 * the wrong thing) and so we use the current header version
   8.145 +	 * which they don't support.
   8.146 +	 */
   8.147 +	if (plover_system_arch_is_x86())
   8.148 +		razor_set_set_header_version(set, 1);
   8.149 +#endif
   8.150 +
   8.151 +	return set;
   8.152  }
     9.1 --- a/plover/plover.h	Thu Nov 10 11:00:49 2011 +0000
     9.2 +++ b/plover/plover.h	Thu Nov 10 11:15:09 2011 +0000
     9.3 @@ -40,12 +40,19 @@
     9.4  struct razor_set *plover_razor_set_create_from_yum(const char *base);
     9.5  
     9.6  struct razor_set *plover_relocate_packages(struct razor_set *set,
     9.7 -  const char *base,struct razor_relocations *relocations);
     9.8 -int plover_run_transaction(struct razor_transaction *trans,const char *base,
     9.9 -  const char *install_root,struct razor_set *system,struct razor_set *next,
    9.10 +  struct razor_atomic *atomic,const char *base,
    9.11 +  struct razor_relocations *relocations);
    9.12 +int plover_run_transaction(struct razor_transaction *trans,
    9.13 +  struct razor_install_iterator *ii,const char *base,const char *install_root,
    9.14 +  struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic,
    9.15 +  struct razor_relocations *relocations,enum razor_stage_type stage);
    9.16 +int plover_commit_transaction(struct razor_transaction *trans,const char *base,
    9.17 +  const char *install_root,struct razor_root *root,struct razor_atomic *atomic,
    9.18    struct razor_relocations *relocations);
    9.19  int plover_install(const char *base,const char *prefix,char **pkgs);
    9.20 +int plover_update(const char *base,const char *prefix,char **pkgs);
    9.21  int plover_remove(char **pkgs);
    9.22 +int plover_installed_files_match_prefix(const char *prefix);
    9.23  
    9.24  struct comps *plover_comps_new(void);
    9.25  struct comps *plover_comps_new_from_file(const char *filename);
    10.1 --- a/plover/razor.c	Thu Nov 10 11:00:49 2011 +0000
    10.2 +++ b/plover/razor.c	Thu Nov 10 11:15:09 2011 +0000
    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  J. Ali Harlow <ali@juiblex.co.uk>
    10.8 + * Copyright (C) 2009, 2011  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 @@ -39,7 +39,8 @@
   10.13  }
   10.14  
   10.15  struct razor_set *plover_relocate_packages(struct razor_set *set,
   10.16 -  const char *base,struct razor_relocations *relocations)
   10.17 +  struct razor_atomic *atomic,const char *base,
   10.18 +  struct razor_relocations *relocations)
   10.19  {
   10.20      struct razor_importer *importer;
   10.21      struct razor_property_iterator *prop_iter;
   10.22 @@ -48,6 +49,7 @@
   10.23      struct razor_package *package;
   10.24      struct razor_property *property;
   10.25      struct razor_rpm *rpm;
   10.26 +    struct razor_set *new;
   10.27      const char *name,*version,*arch,*summary,*desc,*url,*license;
   10.28      char *s,*file;
   10.29      uint32_t flags;
   10.30 @@ -61,16 +63,14 @@
   10.31  	s=rpm_filename(name,version,arch);
   10.32  	file=plover_strconcat(base,"/rpms/",s,NULL);
   10.33  	free(s);
   10.34 -	rpm=razor_rpm_open(file);
   10.35 +	rpm=razor_rpm_open(file,atomic);
   10.36 +	free(file);
   10.37  	if (!rpm)
   10.38  	{
   10.39 -	    fprintf(stderr,"failed to open rpm %s\n",file);
   10.40  	    razor_package_iterator_destroy(pkg_iter);
   10.41  	    razor_importer_destroy(importer);
   10.42 -	    free(file);
   10.43  	    return NULL;
   10.44  	}
   10.45 -	free(file);
   10.46  	razor_relocations_set_rpm(relocations,rpm);
   10.47  	razor_rpm_close(rpm);
   10.48  	razor_importer_begin_package(importer,name,version,arch);
   10.49 @@ -90,70 +90,113 @@
   10.50  	razor_importer_finish_package(importer);
   10.51      }
   10.52      razor_package_iterator_destroy(pkg_iter);
   10.53 -    return razor_importer_finish(importer);
   10.54 +    new=razor_importer_finish(importer);
   10.55 +    if (new)
   10.56 +	razor_set_set_header_version(new,razor_set_get_header_version(set));
   10.57 +    return new;
   10.58  }
   10.59  
   10.60 -int plover_run_transaction(struct razor_transaction *trans,const char *base,
   10.61 -  const char *install_root,struct razor_set *system,struct razor_set *next,
   10.62 -  struct razor_relocations *relocations)
   10.63 +int plover_run_transaction(struct razor_transaction *trans,
   10.64 +  struct razor_install_iterator *ii,const char *base,const char *install_root,
   10.65 +  struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic,
   10.66 +  struct razor_relocations *relocations,enum razor_stage_type stage)
   10.67  {
   10.68 -    struct razor_install_iterator *ii;
   10.69      struct razor_package *package;
   10.70      enum razor_install_action action;
   10.71      struct razor_rpm *rpm;
   10.72      const char *name,*version,*arch;
   10.73      char *s,*file;
   10.74      int count;
   10.75 -    ii=razor_set_create_install_iterator(system,next);
   10.76 -    printf("Running Transaction\n");
   10.77 +    razor_install_iterator_rewind(ii);
   10.78 +    switch(stage)
   10.79 +    {
   10.80 +	case RAZOR_STAGE_SCRIPTS_PRE:
   10.81 +	    printf("Running pre-transaction scripts\n");
   10.82 +	    break;
   10.83 +	case RAZOR_STAGE_FILES:
   10.84 +	    printf("Running Transaction\n");
   10.85 +	    break;
   10.86 +	case RAZOR_STAGE_SCRIPTS_POST:
   10.87 +	    printf("Running post-transaction scripts\n");
   10.88 +	    break;
   10.89 +	default:
   10.90 +	    /* Keep the compiler happy */
   10.91 +	    break;
   10.92 +    }
   10.93      while (razor_install_iterator_next(ii,&package,&action,&count))
   10.94      {
   10.95  	if (action==RAZOR_INSTALL_ACTION_REMOVE)
   10.96  	{
   10.97  	    razor_package_get_details(system,package,RAZOR_DETAIL_NAME,&name,
   10.98  	      RAZOR_DETAIL_LAST);
   10.99 -	    printf("  Removing : %s ",name);
  10.100 -	    if (razor_package_remove(system,next,package,install_root,count)<0)
  10.101 -		printf(
  10.102 -		  "\nWarning: one or more errors occurred while removing %s",
  10.103 -		  name);
  10.104 -	    printf("\n");
  10.105 +	    if (stage==RAZOR_STAGE_FILES)
  10.106 +		printf("  Removing : %s ",name);
  10.107 +	    razor_package_remove(system,next,atomic,package,install_root,
  10.108 +	      count,stage);
  10.109 +	    if (stage==RAZOR_STAGE_FILES)
  10.110 +		printf("\n");
  10.111  	}
  10.112  	else
  10.113  	{
  10.114  	    razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
  10.115  	      RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
  10.116  	      RAZOR_DETAIL_LAST);
  10.117 -	    printf("  Installing : %s ",name);
  10.118  	    s=rpm_filename(name,version,arch);
  10.119  	    file=plover_strconcat(base,"/rpms/",s,NULL);
  10.120  	    free(s);
  10.121 -	    rpm=razor_rpm_open(file);
  10.122 +	    rpm=razor_rpm_open(file,atomic);
  10.123 +	    free(file);
  10.124  	    if (!rpm)
  10.125 -	    {
  10.126 -		fprintf(stderr,"failed to open rpm %s\n",file);
  10.127 -		free(file);
  10.128 -		razor_install_iterator_destroy(ii);
  10.129  		return -1;
  10.130 -	    }
  10.131 +	    if (stage==RAZOR_STAGE_FILES)
  10.132 +		printf("  Installing : %s ",name);
  10.133  	    if (relocations)
  10.134  		razor_rpm_set_relocations(rpm,relocations);
  10.135  	    razor_transaction_fixup_package(trans,package,rpm);
  10.136 -	    if (razor_rpm_install(rpm,install_root,1)<0)
  10.137 -	    {
  10.138 -		fprintf(stderr,"failed to install rpm %s\n",file);
  10.139 -		razor_rpm_close(rpm);
  10.140 -		free(file);
  10.141 -		razor_install_iterator_destroy(ii);
  10.142 -		return -1;
  10.143 -	    }
  10.144 +	    razor_rpm_install(rpm,atomic,install_root,1,stage);
  10.145  	    razor_rpm_close(rpm);
  10.146 -	    free(file);
  10.147 -	    printf("\n");
  10.148 +	    if (stage==RAZOR_STAGE_FILES)
  10.149 +		printf("\n");
  10.150  	}
  10.151 +	if (razor_atomic_in_error_state(atomic))
  10.152 +	    return -1;
  10.153      }
  10.154 +    return 0;
  10.155 +}
  10.156 +
  10.157 +/*
  10.158 + * Note: plover_commit_transaction() takes ownership of root which should
  10.159 + * not be used after it returns.
  10.160 + */
  10.161 +int plover_commit_transaction(struct razor_transaction *trans,const char *base,
  10.162 +  const char *install_root,struct razor_root *root,struct razor_atomic *atomic,
  10.163 +  struct razor_relocations *relocations)
  10.164 +{
  10.165 +    int retval;
  10.166 +    struct razor_set *next,*system;
  10.167 +    struct razor_install_iterator *ii;
  10.168 +    razor_transaction_resolve(trans);
  10.169 +    if (razor_transaction_describe(trans)>0)
  10.170 +    {
  10.171 +	razor_root_close(root);
  10.172 +	return -1;
  10.173 +    }
  10.174 +    next=razor_transaction_commit(trans);
  10.175 +    system=razor_root_get_system_set(root);
  10.176 +    ii=razor_set_create_install_iterator(system,next);
  10.177 +    plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
  10.178 +      relocations,RAZOR_STAGE_SCRIPTS_PRE);
  10.179 +    plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
  10.180 +      relocations,RAZOR_STAGE_FILES);
  10.181 +    razor_root_update(root,next);
  10.182 +    razor_root_commit(root);
  10.183 +    retval=razor_atomic_commit(atomic);
  10.184 +    if (!retval)
  10.185 +	plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
  10.186 +	  relocations,RAZOR_STAGE_SCRIPTS_POST);
  10.187 +    razor_set_unref(next);
  10.188      razor_install_iterator_destroy(ii);
  10.189 -    return 0;
  10.190 +    return retval;
  10.191  }
  10.192  
  10.193  static int plover_mark_package_for_update(struct razor_transaction *trans,
  10.194 @@ -180,13 +223,14 @@
  10.195  
  10.196  int plover_install(const char *base,const char *prefix,char **pkgs)
  10.197  {
  10.198 -    int i;
  10.199 +    int i,retval;
  10.200      char *s;
  10.201      char *install_root;
  10.202      struct razor_root *root;
  10.203 -    struct razor_set *system,*set,*upstream,*next;
  10.204 +    struct razor_set *system,*set,*upstream;
  10.205      struct razor_transaction *trans;
  10.206      struct razor_relocations *relocations;
  10.207 +    struct razor_atomic *atomic;
  10.208      install_root=getenv("RAZOR_ROOT");
  10.209      if (!install_root)
  10.210  	install_root="";
  10.211 @@ -195,82 +239,110 @@
  10.212  	relocations=razor_relocations_create();
  10.213  	razor_relocations_add(relocations,"/usr",prefix);
  10.214      }
  10.215 +    else
  10.216 +	relocations=NULL;
  10.217 +    atomic=razor_atomic_open("Install packages");
  10.218      /*
  10.219       * Calling razor_root_open() on a system that hasn't yet had
  10.220       * razor_root_create() run generates a confusing error message
  10.221       * on stderr. Avoid this by trying to open it R/O first which
  10.222       * fails without generating any error.
  10.223       */
  10.224 -    set=razor_root_open_read_only(install_root);
  10.225 +    set=razor_root_open_read_only(install_root,atomic);
  10.226      if (set)
  10.227 -	razor_set_destroy(set);
  10.228 +	razor_set_unref(set);
  10.229      else
  10.230  	razor_root_create(install_root);
  10.231 -    root=razor_root_open(install_root);
  10.232 +    root=razor_root_open(install_root,atomic);
  10.233      if (!root)
  10.234 +    {
  10.235 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.236 +	razor_atomic_destroy(atomic);
  10.237 +	if (relocations)
  10.238 +	    razor_relocations_destroy(relocations);
  10.239  	return -1;
  10.240 +    }
  10.241      system=razor_root_get_system_set(root);
  10.242      if (!system)
  10.243      {
  10.244 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.245  	razor_root_close(root);
  10.246 +	razor_atomic_destroy(atomic);
  10.247 +	if (relocations)
  10.248 +	    razor_relocations_destroy(relocations);
  10.249  	return -1;
  10.250      }
  10.251      s=plover_strconcat(base,"/repodata",NULL);
  10.252 -    if (!s)
  10.253 +    if (s)
  10.254      {
  10.255 +	retval=chdir(s);
  10.256 +	if (retval<0)
  10.257 +	    perror(s);
  10.258 +    }
  10.259 +    else
  10.260 +	retval=-1;
  10.261 +    free(s);
  10.262 +    if (retval<0)
  10.263 +    {
  10.264 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.265  	razor_root_close(root);
  10.266 +	razor_atomic_destroy(atomic);
  10.267 +	if (relocations)
  10.268 +	    razor_relocations_destroy(relocations);
  10.269  	return -1;
  10.270      }
  10.271 -    if (chdir(s)<0)
  10.272 +    set=plover_razor_set_create_from_yum(base);
  10.273 +    if (set)
  10.274      {
  10.275 -	perror(s);
  10.276 -	free(s);
  10.277 +	upstream=plover_relocate_packages(set,atomic,base,relocations);
  10.278 +	razor_set_unref(set);
  10.279 +    }
  10.280 +    else
  10.281 +	upstream=NULL;
  10.282 +    if (!upstream)
  10.283 +    {
  10.284 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.285  	razor_root_close(root);
  10.286 +	razor_atomic_destroy(atomic);
  10.287 +	if (relocations)
  10.288 +	    razor_relocations_destroy(relocations);
  10.289  	return -1;
  10.290      }
  10.291 -    free(s);
  10.292 -    set=plover_razor_set_create_from_yum(base);
  10.293 -    if (!set)
  10.294 -    {
  10.295 -	razor_root_close(root);
  10.296 -	return -1;
  10.297 -    }
  10.298 -    upstream=plover_relocate_packages(set,base,relocations);
  10.299 -    razor_set_destroy(set);
  10.300      trans=razor_transaction_create(system,upstream);
  10.301 +    razor_set_unref(upstream);
  10.302      for(i=0;pkgs[i];i++)
  10.303  	if (plover_mark_package_for_update(trans,system,pkgs[i]) &&
  10.304  	  plover_mark_package_for_update(trans,upstream,pkgs[i]))
  10.305  	{
  10.306  	    fprintf(stderr,"%s: Package not found\n",pkgs[i]);
  10.307 -	    razor_root_close(root);
  10.308 -	    return -1;
  10.309 +	    retval=-1;
  10.310 +	    break;
  10.311  	}
  10.312 -    razor_transaction_resolve(trans);
  10.313 -    if (razor_transaction_describe(trans)>0)
  10.314 +    if (!retval)
  10.315      {
  10.316 +	retval=plover_commit_transaction(trans,base,install_root,root,atomic,
  10.317 +	  relocations);
  10.318 +	if (retval)
  10.319 +	    fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.320 +    }
  10.321 +    else
  10.322  	razor_root_close(root);
  10.323 -	return -1;
  10.324 -    }
  10.325 -    next=razor_transaction_commit(trans);
  10.326 -    plover_run_transaction(trans,base,install_root,system,next,relocations);
  10.327 -    razor_root_update(root,next);
  10.328      razor_transaction_destroy(trans);
  10.329 -    razor_set_destroy(next);
  10.330 -    razor_set_destroy(upstream);
  10.331 -    if (prefix)
  10.332 +    razor_atomic_destroy(atomic);
  10.333 +    if (relocations)
  10.334  	razor_relocations_destroy(relocations);
  10.335 -    return razor_root_commit(root);
  10.336 +    return retval;
  10.337  }
  10.338  
  10.339  int plover_update(const char *base,const char *prefix,char **pkgs)
  10.340  {
  10.341 -    int i;
  10.342 +    int i,retval;
  10.343      char *install_root,*s;
  10.344      struct razor_root *root;
  10.345 -    struct razor_set *system,*set,*upstream,*next;
  10.346 +    struct razor_set *system,*set,*upstream;
  10.347      struct razor_transaction *trans;
  10.348      struct razor_relocations *relocations;
  10.349 +    struct razor_atomic *atomic;
  10.350      install_root=getenv("RAZOR_ROOT");
  10.351      if (!install_root)
  10.352  	install_root="";
  10.353 @@ -279,73 +351,101 @@
  10.354  	relocations=razor_relocations_create();
  10.355  	razor_relocations_add(relocations,"/usr",prefix);
  10.356      }
  10.357 -    set=razor_root_open_read_only(install_root);
  10.358 +    else
  10.359 +	relocations=NULL;
  10.360 +    atomic=razor_atomic_open("Update packages");
  10.361 +    set=razor_root_open_read_only(install_root,atomic);
  10.362      if (!set)
  10.363 +    {
  10.364 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.365 +	razor_atomic_destroy(atomic);
  10.366 +	if (relocations)
  10.367 +	    razor_relocations_destroy(relocations);
  10.368  	return 0;
  10.369 -    razor_set_destroy(set);
  10.370 -    root=razor_root_open(install_root);
  10.371 +    }
  10.372 +    razor_set_unref(set);
  10.373 +    root=razor_root_open(install_root,atomic);
  10.374      if (!root)
  10.375 +    {
  10.376 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.377 +	razor_atomic_destroy(atomic);
  10.378 +	if (relocations)
  10.379 +	    razor_relocations_destroy(relocations);
  10.380  	return -1;
  10.381 +    }
  10.382      system=razor_root_get_system_set(root);
  10.383      if (!system)
  10.384      {
  10.385 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.386  	razor_root_close(root);
  10.387 +	razor_atomic_destroy(atomic);
  10.388 +	if (relocations)
  10.389 +	    razor_relocations_destroy(relocations);
  10.390  	return -1;
  10.391      }
  10.392      s=plover_strconcat(base,"/repodata",NULL);
  10.393 -    if (!s)
  10.394 +    if (s)
  10.395      {
  10.396 +	retval=chdir(s);
  10.397 +	if (retval)
  10.398 +	    perror(s);
  10.399 +    }
  10.400 +    else
  10.401 +	retval=-1;
  10.402 +    free(s);
  10.403 +    if (retval)
  10.404 +    {
  10.405 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.406  	razor_root_close(root);
  10.407 +	razor_atomic_destroy(atomic);
  10.408 +	if (relocations)
  10.409 +	    razor_relocations_destroy(relocations);
  10.410  	return -1;
  10.411      }
  10.412 -    if (chdir(s)<0)
  10.413 +    set=plover_razor_set_create_from_yum(base);
  10.414 +    if (set)
  10.415      {
  10.416 -	perror(s);
  10.417 -	free(s);
  10.418 +	upstream=plover_relocate_packages(set,atomic,base,relocations);
  10.419 +	razor_set_unref(set);
  10.420 +    }
  10.421 +    else
  10.422 +	upstream=NULL;
  10.423 +    if (!upstream)
  10.424 +    {
  10.425 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.426  	razor_root_close(root);
  10.427 +	razor_atomic_destroy(atomic);
  10.428 +	if (relocations)
  10.429 +	    razor_relocations_destroy(relocations);
  10.430  	return -1;
  10.431      }
  10.432 -    free(s);
  10.433 -    set=plover_razor_set_create_from_yum(base);
  10.434 -    if (!set)
  10.435 -    {
  10.436 -	razor_root_close(root);
  10.437 -	return -1;
  10.438 -    }
  10.439 -    upstream=plover_relocate_packages(set,base,relocations);
  10.440 -    razor_set_destroy(set);
  10.441      trans=razor_transaction_create(system,upstream);
  10.442 +    razor_set_unref(upstream);
  10.443      if (pkgs)
  10.444  	for(i=0;pkgs[i];i++)
  10.445  	{
  10.446  	    if (plover_mark_package_for_update(trans,system,pkgs[i]))
  10.447  	    {
  10.448  		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
  10.449 -		razor_transaction_destroy(trans);
  10.450 -		razor_set_destroy(upstream);
  10.451 -		razor_set_destroy(system);
  10.452 -		razor_root_close(root);
  10.453 -		return -1;
  10.454 +		retval=-1;
  10.455 +		break;
  10.456  	    }
  10.457  	}
  10.458      else
  10.459  	razor_transaction_update_all(trans);
  10.460 -    razor_transaction_resolve(trans);
  10.461 -    if (razor_transaction_describe(trans)>0)
  10.462 -    {
  10.463 -	razor_transaction_destroy(trans);
  10.464 -	razor_set_destroy(upstream);
  10.465 -	razor_set_destroy(system);
  10.466 +    if (!retval) {
  10.467 +	retval=plover_commit_transaction(trans,base,install_root,root,atomic,
  10.468 +	  relocations);
  10.469 +	if (retval)
  10.470 +	    fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.471 +    }
  10.472 +    else
  10.473  	razor_root_close(root);
  10.474 -	return -1;
  10.475 -    }
  10.476 -    next=razor_transaction_commit(trans);
  10.477 -    plover_run_transaction(trans,base,install_root,system,next,relocations);
  10.478 -    razor_root_update(root,next);
  10.479      razor_transaction_destroy(trans);
  10.480 -    razor_set_destroy(next);
  10.481 -    razor_set_destroy(upstream);
  10.482 -    return razor_root_commit(root);
  10.483 +    if (relocations)
  10.484 +	razor_relocations_destroy(relocations);
  10.485 +    razor_atomic_destroy(atomic);
  10.486 +    return retval;
  10.487  }
  10.488  
  10.489  static int plover_mark_packages_for_removal(struct razor_transaction *trans,
  10.490 @@ -371,58 +471,108 @@
  10.491  
  10.492  int plover_remove(char **pkgs)
  10.493  {
  10.494 -    int i;
  10.495 +    int i,retval=0;
  10.496      char *install_root;
  10.497      struct razor_root *root;
  10.498 -    struct razor_set *system,*set,*upstream,*next;
  10.499 +    struct razor_set *system,*set,*upstream;
  10.500      struct razor_transaction *trans;
  10.501 +    struct razor_atomic *atomic;
  10.502      install_root=getenv("RAZOR_ROOT");
  10.503      if (!install_root)
  10.504  	install_root="";
  10.505 -    set=razor_root_open_read_only(install_root);
  10.506 +    atomic=razor_atomic_open("Remove packages");
  10.507 +    set=razor_root_open_read_only(install_root,atomic);
  10.508      if (!set)
  10.509 +    {
  10.510 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.511 +	razor_atomic_destroy(atomic);
  10.512  	return 0;
  10.513 -    razor_set_destroy(set);
  10.514 -    root=razor_root_open(install_root);
  10.515 +    }
  10.516 +    razor_set_unref(set);
  10.517 +    root=razor_root_open(install_root,atomic);
  10.518      if (!root)
  10.519 +    {
  10.520 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.521 +	razor_atomic_destroy(atomic);
  10.522  	return -1;
  10.523 +    }
  10.524      system=razor_root_get_system_set(root);
  10.525      if (!system)
  10.526      {
  10.527 +	fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.528  	razor_root_close(root);
  10.529 +	razor_atomic_destroy(atomic);
  10.530  	return -1;
  10.531      }
  10.532      upstream=razor_set_create_without_root();
  10.533      trans=razor_transaction_create(system,upstream);
  10.534 +    razor_set_unref(upstream);
  10.535      if (pkgs)
  10.536  	for(i=0;pkgs[i];i++)
  10.537  	{
  10.538  	    if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
  10.539  	    {
  10.540  		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
  10.541 -		razor_transaction_destroy(trans);
  10.542 -		razor_set_destroy(upstream);
  10.543 -		razor_set_destroy(system);
  10.544 -		razor_root_close(root);
  10.545 -		return -1;
  10.546 +		retval=-1;
  10.547 +		break;
  10.548  	    }
  10.549  	}
  10.550      else
  10.551  	plover_mark_packages_for_removal(trans,system,NULL);
  10.552 -    razor_transaction_resolve(trans);
  10.553 -    if (razor_transaction_describe(trans)>0)
  10.554 +    if (!retval)
  10.555      {
  10.556 -	razor_transaction_destroy(trans);
  10.557 -	razor_set_destroy(upstream);
  10.558 -	razor_set_destroy(system);
  10.559 +	retval=
  10.560 +	  plover_commit_transaction(trans,NULL,install_root,root,atomic,NULL);
  10.561 +	if (retval)
  10.562 +	    fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
  10.563 +    }
  10.564 +    else
  10.565  	razor_root_close(root);
  10.566 -	return -1;
  10.567 +    razor_transaction_destroy(trans);
  10.568 +    razor_atomic_destroy(atomic);
  10.569 +    return retval;
  10.570 +}
  10.571 +
  10.572 +/*
  10.573 + * Note: If there are no installed files, then any prefix will match.
  10.574 + */
  10.575 +
  10.576 +int plover_installed_files_match_prefix(const char *prefix)
  10.577 +{
  10.578 +    int len,matches=1;
  10.579 +    const char *name;
  10.580 +    char *install_root;
  10.581 +    struct razor_set *set;
  10.582 +    struct razor_atomic *atomic;
  10.583 +    struct razor_package *package;
  10.584 +    struct razor_package_iterator *pi;
  10.585 +    struct razor_file_iterator *fi;
  10.586 +    len=strlen(prefix);
  10.587 +    while(len && prefix[len-1]=='/')
  10.588 +	len--;
  10.589 +    install_root=getenv("RAZOR_ROOT");
  10.590 +    if (!install_root)
  10.591 +	install_root="";
  10.592 +    atomic=razor_atomic_open("Query packages");
  10.593 +    set=razor_root_open_read_only(install_root,atomic);
  10.594 +    if (set)
  10.595 +    {
  10.596 +	pi=razor_package_iterator_create(set);
  10.597 +	while (matches &&
  10.598 +	  razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
  10.599 +	{
  10.600 +	    fi=razor_file_iterator_create(set,package,0);
  10.601 +	    while (matches && razor_file_iterator_next(fi,&name))
  10.602 +	    {
  10.603 +		if (strncmp(name,prefix,len) ||
  10.604 +		  name[len]!='\0' && name[len]!='/')
  10.605 +		    matches=0;
  10.606 +	    }
  10.607 +	    razor_file_iterator_destroy(fi);
  10.608 +	}
  10.609 +	razor_package_iterator_destroy(pi);
  10.610 +	razor_set_unref(set);
  10.611      }
  10.612 -    next=razor_transaction_commit(trans);
  10.613 -    plover_run_transaction(trans,NULL,install_root,system,next,NULL);
  10.614 -    razor_root_update(root,next);
  10.615 -    razor_transaction_destroy(trans);
  10.616 -    razor_set_destroy(next);
  10.617 -    razor_set_destroy(upstream);
  10.618 -    return razor_root_commit(root);
  10.619 +    razor_atomic_destroy(atomic);
  10.620 +    return matches;
  10.621  }
    11.1 --- a/plover/util.c	Thu Nov 10 11:00:49 2011 +0000
    11.2 +++ b/plover/util.c	Thu Nov 10 11:15:09 2011 +0000
    11.3 @@ -1,5 +1,5 @@
    11.4  /*
    11.5 - * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
    11.6 + * Copyright (C) 2009, 2011  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 @@ -60,10 +60,30 @@
   11.11  char *plover_default_prefix_for_vendor(const char *vendor)
   11.12  {
   11.13  #ifdef WIN32
   11.14 -    char path[PATH_MAX];
   11.15 -    SHGetFolderPath(NULL,CSIDL_PROGRAM_FILES|CSIDL_FLAG_DONT_VERIFY,NULL,0,
   11.16 -      path);
   11.17 -    return plover_strconcat(path,"\\",vendor?vendor:"Plover",NULL);
   11.18 +    /*
   11.19 +     * We want to sidestep any redirecting that MS-Windows may
   11.20 +     * introduce since this will be based on the architecture
   11.21 +     * of the installer whereas the architecture that actually
   11.22 +     * matters is of the packages (checked elsewhere).
   11.23 +     */
   11.24 +    BOOL is_wow64=FALSE;
   11.25 +    typedef BOOL (WINAPI *is_wow64_process_t)(HANDLE,PBOOL);
   11.26 +    is_wow64_process_t is_wow64_process;
   11.27 +    char *program_files=NULL;
   11.28 +    char buf[PATH_MAX];
   11.29 +    is_wow64_process=(is_wow64_process_t)
   11.30 +      GetProcAddress(GetModuleHandleA("kernel32"),"IsWow64Process");
   11.31 +    if (is_wow64_process)
   11.32 +	is_wow64_process(GetCurrentProcess(),&is_wow64);
   11.33 +    if (is_wow64)
   11.34 +	program_files=getenv("ProgramW6432");
   11.35 +    if (!program_files)
   11.36 +    {
   11.37 +	SHGetFolderPath(NULL,CSIDL_PROGRAM_FILES|CSIDL_FLAG_DONT_VERIFY,NULL,0,
   11.38 +	  buf);
   11.39 +	program_files=buf;
   11.40 +    }
   11.41 +    return plover_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL);
   11.42  #else
   11.43      return NULL;
   11.44  #endif
    12.1 --- a/setup/Makefile.am	Thu Nov 10 11:00:49 2011 +0000
    12.2 +++ b/setup/Makefile.am	Thu Nov 10 11:15:09 2011 +0000
    12.3 @@ -7,13 +7,13 @@
    12.4  setup_SOURCES=setup.c
    12.5  setup_LDFLAGS=-all-static
    12.6  if HAVE_WINDRES
    12.7 -setup_SOURCES+=resources.rc
    12.8 +setup_SOURCES+=resources.rc setup.exe.manifest
    12.9  endif
   12.10  
   12.11  .png.pnm:
   12.12  	pngtopnm $< | pnmquant 256 > $@
   12.13  
   12.14 -resources.$(OBJEXT): resources.rc setup.ico
   12.15 +resources.$(OBJEXT): resources.rc setup.exe.manifest setup.ico
   12.16  	$(WINDRES) resources.rc $@
   12.17  
   12.18  setup.ico:     icon16.pnm icon22.pnm icon32.pnm
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/setup/manifest.xml.in	Thu Nov 10 11:15:09 2011 +0000
    13.3 @@ -0,0 +1,22 @@
    13.4 +changequote([,])dnl
    13.5 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    13.6 +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    13.7 +  <assemblyIdentity
    13.8 +    version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
    13.9 +    name="The plover development team.plover.setup" type="win32"
   13.10 +    processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
   13.11 +  <description>Plover setup program</description>
   13.12 +  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
   13.13 +    <application>
   13.14 +      <!-- Windows 7 functionality -->
   13.15 +      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   13.16 +    </application>
   13.17 +  </compatibility>
   13.18 +  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   13.19 +    <security>
   13.20 +      <requestedPrivileges>
   13.21 +        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
   13.22 +      </requestedPrivileges>
   13.23 +    </security>
   13.24 +  </trustInfo>
   13.25 +</assembly>
    14.1 --- a/setup/resources.rc.in	Thu Nov 10 11:00:49 2011 +0000
    14.2 +++ b/setup/resources.rc.in	Thu Nov 10 11:15:09 2011 +0000
    14.3 @@ -1,4 +1,5 @@
    14.4  #include <winver.h>
    14.5 +#include <winuser.h>
    14.6  
    14.7  MAINICON ICON "setup.ico"
    14.8  
    14.9 @@ -19,7 +20,7 @@
   14.10  		VALUE "FileVersion","@PACKAGE_VERSION@"
   14.11  		VALUE "InternalName","setup"
   14.12  		VALUE "LegalCopyright",
   14.13 -		  "Copyright (c) 2009 J. Ali Harlow et al"
   14.14 +		  "Copyright (c) 2009,2011 J. Ali Harlow et al"
   14.15  		VALUE "OriginalFilename","setup.exe"
   14.16  		VALUE "ProductName","plover"
   14.17  		VALUE "ProductVersion","@PACKAGE_VERSION@"
   14.18 @@ -30,3 +31,5 @@
   14.19  	    VALUE "Translation",0x809,0x4B0
   14.20  	}
   14.21      }
   14.22 +
   14.23 +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "setup.exe.manifest"
    15.1 --- a/setup/setup.c	Thu Nov 10 11:00:49 2011 +0000
    15.2 +++ b/setup/setup.c	Thu Nov 10 11:15:09 2011 +0000
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
    15.6 + * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
    15.7   *
    15.8   * This program is free software; you can redistribute it and/or modify
    15.9   * it under the terms of the GNU General Public License as published by
   15.10 @@ -75,21 +75,10 @@
   15.11      free(vector);
   15.12  }
   15.13  
   15.14 -static void *alloc_lua(void *user_data,void *ptr,size_t osize,size_t nsize)
   15.15 -{
   15.16 -    if (!nsize)
   15.17 -    {
   15.18 -	free(ptr);
   15.19 -	return NULL;
   15.20 -    }
   15.21 -    else
   15.22 -	return realloc(ptr,nsize);
   15.23 -}
   15.24 -
   15.25  void setup(const char *argv0)
   15.26  {
   15.27      char *path,*s,*prefix;
   15.28 -    int changed;
   15.29 +    int ch,changed;
   15.30      struct comps *comps;
   15.31      struct comps_group *group;
   15.32      struct comps_requirement *pkg;
   15.33 @@ -104,6 +93,18 @@
   15.34      }
   15.35      free(s);
   15.36      prefix=plover_default_prefix_for_vendor(comps->vendor);
   15.37 +    if (!plover_installed_files_match_prefix(prefix))
   15.38 +    {
   15.39 +	printf("The existing installation is not under %s\n"
   15.40 +	  "In order to continue, all the existing packages must be removed.\n"
   15.41 +	  "Do you want to remove all existing packages? ",prefix);
   15.42 +	ch=getchar();
   15.43 +	if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n')
   15.44 +	    exit(1);
   15.45 +	while(ch!='\n' && ch!=EOF)
   15.46 +	    ch=getchar();
   15.47 +	plover_remove(NULL);
   15.48 +    }
   15.49      group=plover_comps_lookup_group(comps,"base");
   15.50      if (!group)
   15.51      {
   15.52 @@ -148,4 +149,5 @@
   15.53  	plover_remove(NULL);
   15.54      else
   15.55  	setup(argv[0]);
   15.56 +    exit(0);
   15.57  }
    16.1 --- a/update/Makefile.am	Thu Nov 10 11:00:49 2011 +0000
    16.2 +++ b/update/Makefile.am	Thu Nov 10 11:15:09 2011 +0000
    16.3 @@ -7,13 +7,13 @@
    16.4  update_SOURCES=update.c
    16.5  update_LDFLAGS=-all-static
    16.6  if HAVE_WINDRES
    16.7 -update_SOURCES+=resources.rc
    16.8 +update_SOURCES+=resources.rc update.exe.manifest
    16.9  endif
   16.10  
   16.11  .png.pnm:
   16.12  	pngtopnm $< | pnmquant 256 > $@
   16.13  
   16.14 -resources.$(OBJEXT): resources.rc update.ico
   16.15 +resources.$(OBJEXT): resources.rc update.exe.manifest update.ico
   16.16  	$(WINDRES) resources.rc $@
   16.17  
   16.18  update.ico:     icon16.pnm icon22.pnm icon32.pnm
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/update/manifest.xml.in	Thu Nov 10 11:15:09 2011 +0000
    17.3 @@ -0,0 +1,22 @@
    17.4 +changequote([,])dnl
    17.5 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    17.6 +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    17.7 +  <assemblyIdentity
    17.8 +    version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
    17.9 +    name="The plover development team.plover.update" type="win32"
   17.10 +    processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
   17.11 +  <description>Plover update program</description>
   17.12 +  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
   17.13 +    <application>
   17.14 +      <!-- Windows 7 functionality -->
   17.15 +      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   17.16 +    </application>
   17.17 +  </compatibility>
   17.18 +  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   17.19 +    <security>
   17.20 +      <requestedPrivileges>
   17.21 +        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
   17.22 +      </requestedPrivileges>
   17.23 +    </security>
   17.24 +  </trustInfo>
   17.25 +</assembly>
    18.1 --- a/update/resources.rc.in	Thu Nov 10 11:00:49 2011 +0000
    18.2 +++ b/update/resources.rc.in	Thu Nov 10 11:15:09 2011 +0000
    18.3 @@ -1,4 +1,5 @@
    18.4  #include <winver.h>
    18.5 +#include <winuser.h>
    18.6  
    18.7  MAINICON ICON "update.ico"
    18.8  
    18.9 @@ -15,11 +16,11 @@
   18.10  	    BLOCK "080904B0"
   18.11  	    {
   18.12  		VALUE "CompanyName","The plover development team"
   18.13 -		VALUE "FileDescription","Plover setup program"
   18.14 +		VALUE "FileDescription","Plover update program"
   18.15  		VALUE "FileVersion","@PACKAGE_VERSION@"
   18.16  		VALUE "InternalName","update"
   18.17  		VALUE "LegalCopyright",
   18.18 -		  "Copyright (c) 2009 J. Ali Harlow et al"
   18.19 +		  "Copyright (c) 2009,2011 J. Ali Harlow et al"
   18.20  		VALUE "OriginalFilename","update.exe"
   18.21  		VALUE "ProductName","plover"
   18.22  		VALUE "ProductVersion","@PACKAGE_VERSION@"
   18.23 @@ -30,3 +31,5 @@
   18.24  	    VALUE "Translation",0x809,0x4B0
   18.25  	}
   18.26      }
   18.27 +
   18.28 +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update.exe.manifest"
    19.1 --- a/update/update.c	Thu Nov 10 11:00:49 2011 +0000
    19.2 +++ b/update/update.c	Thu Nov 10 11:15:09 2011 +0000
    19.3 @@ -1,5 +1,5 @@
    19.4  /*
    19.5 - * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
    19.6 + * Copyright (C) 2009, 2011  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 @@ -17,6 +17,7 @@
   19.11   */
   19.12  
   19.13  #include <stdlib.h>
   19.14 +#include <stdio.h>
   19.15  #include <lua.h>
   19.16  #include "config.h"
   19.17  #include "plover/plover.h"
   19.18 @@ -27,6 +28,7 @@
   19.19  void update(const char *argv0)
   19.20  {
   19.21      char *path,*s,*prefix;
   19.22 +    int ch;
   19.23      struct comps *comps;
   19.24      path=plover_get_program_directory(argv0);
   19.25      s=plover_strconcat(path,"/repodata/comps.xml",NULL);
   19.26 @@ -38,6 +40,18 @@
   19.27      }
   19.28      free(s);
   19.29      prefix=plover_default_prefix_for_vendor(comps->vendor);
   19.30 +    if (!plover_installed_files_match_prefix(prefix))
   19.31 +    {
   19.32 +	printf("The existing installation is not under %s\n"
   19.33 +	  "In order to continue, all the existing packages must be removed.\n"
   19.34 +	  "Do you want to remove all existing packages? ",prefix);
   19.35 +	ch=getchar();
   19.36 +	if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n')
   19.37 +	    exit(1);
   19.38 +	while(ch!='\n' && ch!=EOF)
   19.39 +	    ch=getchar();
   19.40 +	plover_remove(NULL);
   19.41 +    }
   19.42      plover_comps_free(comps);
   19.43      plover_update(path,prefix,NULL);
   19.44      free(prefix);
   19.45 @@ -49,4 +63,5 @@
   19.46      razor_set_lua_loader("posix",luaopen_posix);
   19.47      razor_set_lua_loader("whelk",luaopen_whelk);
   19.48      update(argv[0]);
   19.49 +    exit(0);
   19.50  }