From: J. Ali Harlow Date: Thu, 10 Nov 2011 11:15:09 +0000 (+0000) Subject: Support razor 0.5 (atomic transactions). X-Git-Tag: 0.4~1 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=838e226b84e0cefdb1e55dc50c1a28eabab10931;p=plover.git 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. --- diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..d77ee8c --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,8 @@ +# Usage: +# PLOVER_MSWIN_MANIFEST([output],[input]) +AC_DEFUN([PLOVER_MSWIN_MANIFEST],[m4_foreach_w([PLOVER_File],[$1], + [m4_define([PLOVER_Output],m4_bpatsubst(PLOVER_File,[:.*],[])) + AC_CONFIG_FILES(PLOVER_File, + [m4] PLOVER_Output [>] PLOVER_Output[.new;] + [mv] PLOVER_Output[.new] PLOVER_Output + )])]) diff --git a/app-manager/Makefile.am b/app-manager/Makefile.am index b73f511..0902882 100644 --- a/app-manager/Makefile.am +++ b/app-manager/Makefile.am @@ -5,7 +5,7 @@ bin_PROGRAMS=app-manager app_manager_SOURCES=app-manager.c app-manager.h packagelist.c applications.c \ localmedia.c localmedia.h if HAVE_WINDRES -app_manager_SOURCES+=resources.rc +app_manager_SOURCES+=resources.rc app-manager.exe.manifest endif uidir=$(pkgdatadir) ui_DATA=app-manager.ui @@ -21,7 +21,7 @@ bigicon_DATA=48x48/plover-applications.png .rc.$(OBJEXT): $(WINDRES) $< $@ -resources.$(OBJEXT): app-manager.ico +resources.$(OBJEXT): app-manager.ico app-manager.exe.manifest plover-applications%.pnm: plover-applications.svg rsvg -w $* -h $* -f png $< temp.png diff --git a/app-manager/manifest.xml.in b/app-manager/manifest.xml.in new file mode 100644 index 0000000..ae9e9dd --- /dev/null +++ b/app-manager/manifest.xml.in @@ -0,0 +1,22 @@ +changequote([,])dnl + + + + Application Manager + + + + + + + + + + + + + + diff --git a/app-manager/resources.rc.in b/app-manager/resources.rc.in index 470304c..8169b6e 100644 --- a/app-manager/resources.rc.in +++ b/app-manager/resources.rc.in @@ -1,4 +1,5 @@ #include +#include MAINICON ICON "app-manager.ico" diff --git a/configure.ac b/configure.ac index 4c1367e..48037eb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([plover],[0.3],[ali@juiblex.co.uk]) +AC_INIT([plover],[0.4],[ali@juiblex.co.uk]) AC_PREREQ(2.59) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_SRCDIR([plover/plover.h]) @@ -18,6 +18,10 @@ update/resources.rc app-manager/Makefile app-manager/resources.rc ]) +PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in +update/update.exe.manifest:update/manifest.xml.in +app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in +]) AM_INIT_AUTOMAKE(no-define) case $VERSION in *.*.*) @@ -37,6 +41,9 @@ case $VERSION in AC_SUBST(PLOVER_MICRO_VERSION,0) ;; esac +AC_CANONICAL_HOST +AC_SUBST(HOST_OS,$host_os) +AC_SUBST(HOST_CPU,$host_cpu) # libtool versioning for libplover. For a release one of the following # must apply: @@ -47,8 +54,8 @@ esac # increment CURRENT and set AGE and REVISION to 0. # - If the interface is the same as the previous version, increment REVISION. # -lt_current=0 -lt_revision=1 +lt_current=1 +lt_revision=0 lt_age=0 LIBPLOVER_LT_VERSION_INFO="$lt_current:$lt_revision:$lt_age" AC_SUBST(LIBPLOVER_LT_VERSION_INFO) @@ -56,7 +63,7 @@ AC_SUBST(LIBPLOVER_LT_VERSION_INFO) # and likewise for plover-gtk. # lt_current=0 -lt_revision=0 +lt_revision=1 lt_age=0 PLOVER_GTK_LT_VERSION_INFO="$lt_current:$lt_revision:$lt_age" AC_SUBST(PLOVER_GTK_LT_VERSION_INFO) @@ -75,6 +82,9 @@ AM_CONDITIONAL([HAVE_WINDRES],[test x$WINDRES != xno]) # Checks for header files. ################################################## AC_HEADER_STDC +AC_CHECK_HEADERS([winhttp.h],[],[], +[#include +]) ################################################## # Checks for typedefs, structures, and compiler characteristics. @@ -83,7 +93,7 @@ AC_HEADER_STDC ################################################## # Checks for libraries. ################################################## -PKG_CHECK_MODULES(RAZOR,[razor >= 0.2],[:],[RAZOR_LIBS=-lrazor]) +PKG_CHECK_MODULES(RAZOR,[razor >= 0.5],[:],[RAZOR_LIBS=-lrazor]) PKG_CHECK_MODULES(EXPAT,[expat],[:],[EXPAT_LIBS=-lexpat]) PKG_CHECK_MODULES(ZLIB,[zlib],[:],[ZLIB_LIBS=-lz]) PKG_CHECK_MODULES(GIO,[gio-2.0]) diff --git a/plover-gtk/error.h b/plover-gtk/error.h index 9e7800f..640dd36 100644 --- a/plover-gtk/error.h +++ b/plover-gtk/error.h @@ -7,5 +7,6 @@ typedef enum { PLOVER_RAZOR_ERROR_FAILED } PloverRazorError; -#endif /* __PLOVER_ERROR_H__ */ +GQuark plover_razor_error_quark(void); +#endif /* __PLOVER_ERROR_H__ */ diff --git a/plover-gtk/packageset.c b/plover-gtk/packageset.c index ceb009f..ea8881c 100644 --- a/plover-gtk/packageset.c +++ b/plover-gtk/packageset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 J. Ali Harlow + * Copyright (C) 2010, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include "plover/plover.h" @@ -31,6 +32,7 @@ G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT); typedef struct _PloverPackageSetPrivate { + struct razor_atomic *atomic; struct razor_root *root; struct razor_set *set; GSList *packages; @@ -53,14 +55,9 @@ static void plover_package_set_finalize(GObject *obj) { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); if (priv->root) - { - /* priv->set, if set, is owned by priv->root and should not - * be destroyed. - */ razor_root_close(priv->root); - } - else if (priv->set) - razor_set_destroy(priv->set); + if (priv->atomic) + razor_atomic_destroy(priv->atomic); if (G_OBJECT_CLASS(plover_package_set_parent_class)->finalize) G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj); } @@ -68,6 +65,11 @@ static void plover_package_set_finalize(GObject *obj) static void plover_package_set_dispose(GObject *obj) { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); + if (priv->set) + { + razor_set_unref(priv->set); + priv->set=NULL; + } if (G_OBJECT_CLASS(plover_package_set_parent_class)->dispose) G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj); } @@ -102,7 +104,8 @@ PloverPackageSet *plover_package_set_new_from_installed(const char *root, PloverPackageSetPrivate *priv; set=plover_package_set_new(); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); - priv->root=razor_root_open(root); + priv->atomic=razor_atomic_open("Read root package set"); + priv->root=razor_root_open(root,priv->atomic); if (!priv->root) { g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED, @@ -110,7 +113,7 @@ PloverPackageSet *plover_package_set_new_from_installed(const char *root, g_object_unref(set); return NULL; } - priv->set=razor_root_get_system_set(priv->root); + priv->set=razor_set_ref(razor_root_get_system_set(priv->root)); if (!priv->set) { g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED, @@ -132,6 +135,7 @@ PloverPackageSet *plover_package_set_new_from_repository(const char *base, #endif gchar *s; struct razor_set *reloc; + struct razor_atomic *atomic; PloverPackageSet *set; PloverPackageSetPrivate *priv; set=plover_package_set_new(); @@ -164,7 +168,7 @@ PloverPackageSet *plover_package_set_new_from_repository(const char *base, g_free(s); priv->set=plover_razor_set_create_from_yum(".."); #if HAVE_FCHDIR - fchdir(fd); + (void)fchdir(fd); close(fd); #else chdir(wd); @@ -172,8 +176,18 @@ PloverPackageSet *plover_package_set_new_from_repository(const char *base, #endif if (priv->set && relocations) { - reloc=plover_relocate_packages(priv->set,base,relocations); - razor_set_destroy(priv->set); + atomic=razor_atomic_open("Relocate packages"); + reloc=plover_relocate_packages(priv->set,atomic,base,relocations); + if (!reloc) + g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED, + razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + if (!reloc) + { + g_object_unref(set); + return NULL; + } + razor_set_unref(priv->set); priv->set=reloc; } if (!priv->set) diff --git a/plover/import-yum.c b/plover/import-yum.c index e572273..73634e2 100644 --- a/plover/import-yum.c +++ b/plover/import-yum.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc - * Copyright (C) 2009 J. Ali Harlow + * Copyright (C) 2009, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,6 +48,7 @@ enum { YUM_STATE_PROVIDES, YUM_STATE_OBSOLETES, YUM_STATE_CONFLICTS, + YUM_STATE_SKIPPING_PACKAGE, YUM_STATE_FILE }; @@ -93,6 +94,9 @@ yum_primary_start_element(void *data, const char *name, const char **atts) uint32_t pre, relation, flags; int i; + if (ctx->state == YUM_STATE_SKIPPING_PACKAGE) + return; + if (strcmp(name, "metadata") == 0) { for (i = 0; atts[i]; i += 2) { if (strcmp(atts[i], "packages") == 0) @@ -126,8 +130,12 @@ yum_primary_start_element(void *data, const char *name, const char **atts) } razor_build_evr(buffer, sizeof buffer, epoch, version, release); - razor_importer_begin_package(ctx->importer, - ctx->name, buffer, ctx->arch); + if (!strcmp(ctx->arch, "noarch") || + !strcmp(ctx->arch, razor_system_arch())) { + razor_importer_begin_package(ctx->importer, ctx->name, + buffer, ctx->arch); + } else + ctx->state = YUM_STATE_SKIPPING_PACKAGE; } else if (strcmp(name, "summary") == 0) { ctx->p = ctx->summary; ctx->state = YUM_STATE_SUMMARY; @@ -213,9 +221,10 @@ yum_primary_end_element (void *data, const char *name) } if (strcmp(name, "package") == 0) { - razor_importer_add_details(ctx->importer, ctx->summary, - ctx->description, ctx->url, - ctx->license); + if (ctx->state != YUM_STATE_SKIPPING_PACKAGE) + razor_importer_add_details(ctx->importer, ctx->summary, + ctx->description, ctx->url, + ctx->license); XML_StopParser(ctx->current_parser, XML_TRUE); ctx->current_parser = ctx->filelists_parser; @@ -250,7 +259,8 @@ yum_filelists_start_element(void *data, const char *name, const char **atts) const char *pkg, *pkgid; int i; - if (strcmp(name, "package") == 0) { + if (strcmp(name, "package") == 0 && + ctx->state != YUM_STATE_SKIPPING_PACKAGE) { pkg = NULL; pkgid = NULL; for (i = 0; atts[i]; i += 2) { @@ -264,7 +274,8 @@ yum_filelists_start_element(void *data, const char *name, const char **atts) "mismatch for %s: %s vs %s", pkg, pkgid, ctx->pkgid); } else if (strcmp(name, "file") == 0) { - ctx->state = YUM_STATE_FILE; + if (ctx->state != YUM_STATE_SKIPPING_PACKAGE) + ctx->state = YUM_STATE_FILE; ctx->p = ctx->buffer; } } @@ -274,14 +285,27 @@ yum_filelists_end_element (void *data, const char *name) { struct yum_context *ctx = data; - ctx->state = YUM_STATE_BEGIN; if (strcmp(name, "package") == 0) { XML_StopParser(ctx->current_parser, XML_TRUE); ctx->current_parser = ctx->primary_parser; - razor_importer_finish_package(ctx->importer); - } else if (strcmp(name, "file") == 0) - razor_importer_add_file(ctx->importer, ctx->buffer); + if (ctx->state != YUM_STATE_SKIPPING_PACKAGE) + razor_importer_finish_package(ctx->importer); + ctx->state = YUM_STATE_BEGIN; + } else if (strcmp(name, "file") == 0) { + if (ctx->state != YUM_STATE_SKIPPING_PACKAGE) + razor_importer_add_file(ctx->importer, ctx->buffer); + } + if (ctx->state != YUM_STATE_SKIPPING_PACKAGE) + ctx->state = YUM_STATE_BEGIN; +} +static int plover_system_arch_is_x86(void) +{ + const char *arch=razor_system_arch(); + if (!arch || arch[0]!='i' || arch[1]<'3' || arch[1]>'6') + return 0; + else + return !strcmp(arch+2,"86"); } #define XML_BUFFER_SIZE 4096 @@ -291,9 +315,10 @@ plover_razor_set_create_from_yum(const char *base) { struct yum_context ctx; void *buf; - int len, ret; + int len; gzFile primary, filelists; XML_ParsingStatus status; + struct razor_set *set; ctx.importer = razor_importer_create(); ctx.state = YUM_STATE_BEGIN; @@ -329,7 +354,7 @@ plover_razor_set_create_from_yum(const char *base) XML_GetParsingStatus(ctx.current_parser, &status); switch (status.parsing) { case XML_SUSPENDED: - ret = XML_ResumeParser(ctx.current_parser); + XML_ResumeParser(ctx.current_parser); break; case XML_PARSING: case XML_INITIALIZED: @@ -360,5 +385,19 @@ plover_razor_set_create_from_yum(const char *base) gzclose(primary); gzclose(filelists); - return razor_importer_finish(ctx.importer); + set = razor_importer_finish(ctx.importer); +#if RAZOR_HEADER_VERSION_MIN <= 1 + /* + * Header version 1 is supported by plover v0.3 and is used on + * 32-bit intel machines which allows the setup and update + * applications from v0.3 to work. On other machines, we don't + * want these old applications to work (since they would do + * the wrong thing) and so we use the current header version + * which they don't support. + */ + if (plover_system_arch_is_x86()) + razor_set_set_header_version(set, 1); +#endif + + return set; } diff --git a/plover/plover.h b/plover/plover.h index 291d8fc..f2e4293 100644 --- a/plover/plover.h +++ b/plover/plover.h @@ -40,12 +40,19 @@ char *plover_get_program_directory(const char *argv0); struct razor_set *plover_razor_set_create_from_yum(const char *base); struct razor_set *plover_relocate_packages(struct razor_set *set, - const char *base,struct razor_relocations *relocations); -int plover_run_transaction(struct razor_transaction *trans,const char *base, - const char *install_root,struct razor_set *system,struct razor_set *next, + struct razor_atomic *atomic,const char *base, + struct razor_relocations *relocations); +int plover_run_transaction(struct razor_transaction *trans, + struct razor_install_iterator *ii,const char *base,const char *install_root, + struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic, + struct razor_relocations *relocations,enum razor_stage_type stage); +int plover_commit_transaction(struct razor_transaction *trans,const char *base, + const char *install_root,struct razor_root *root,struct razor_atomic *atomic, struct razor_relocations *relocations); int plover_install(const char *base,const char *prefix,char **pkgs); +int plover_update(const char *base,const char *prefix,char **pkgs); int plover_remove(char **pkgs); +int plover_installed_files_match_prefix(const char *prefix); struct comps *plover_comps_new(void); struct comps *plover_comps_new_from_file(const char *filename); diff --git a/plover/razor.c b/plover/razor.c index ecc5e08..772d36b 100644 --- a/plover/razor.c +++ b/plover/razor.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc - * Copyright (C) 2009 J. Ali Harlow + * Copyright (C) 2009, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,7 +39,8 @@ static char *rpm_filename(const char *name,const char *version,const char *arch) } struct razor_set *plover_relocate_packages(struct razor_set *set, - const char *base,struct razor_relocations *relocations) + struct razor_atomic *atomic,const char *base, + struct razor_relocations *relocations) { struct razor_importer *importer; struct razor_property_iterator *prop_iter; @@ -48,6 +49,7 @@ struct razor_set *plover_relocate_packages(struct razor_set *set, struct razor_package *package; struct razor_property *property; struct razor_rpm *rpm; + struct razor_set *new; const char *name,*version,*arch,*summary,*desc,*url,*license; char *s,*file; uint32_t flags; @@ -61,16 +63,14 @@ struct razor_set *plover_relocate_packages(struct razor_set *set, s=rpm_filename(name,version,arch); file=plover_strconcat(base,"/rpms/",s,NULL); free(s); - rpm=razor_rpm_open(file); + rpm=razor_rpm_open(file,atomic); + free(file); if (!rpm) { - fprintf(stderr,"failed to open rpm %s\n",file); razor_package_iterator_destroy(pkg_iter); razor_importer_destroy(importer); - free(file); return NULL; } - free(file); razor_relocations_set_rpm(relocations,rpm); razor_rpm_close(rpm); razor_importer_begin_package(importer,name,version,arch); @@ -90,72 +90,115 @@ struct razor_set *plover_relocate_packages(struct razor_set *set, razor_importer_finish_package(importer); } razor_package_iterator_destroy(pkg_iter); - return razor_importer_finish(importer); + new=razor_importer_finish(importer); + if (new) + razor_set_set_header_version(new,razor_set_get_header_version(set)); + return new; } -int plover_run_transaction(struct razor_transaction *trans,const char *base, - const char *install_root,struct razor_set *system,struct razor_set *next, - struct razor_relocations *relocations) +int plover_run_transaction(struct razor_transaction *trans, + struct razor_install_iterator *ii,const char *base,const char *install_root, + struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic, + struct razor_relocations *relocations,enum razor_stage_type stage) { - struct razor_install_iterator *ii; struct razor_package *package; enum razor_install_action action; struct razor_rpm *rpm; const char *name,*version,*arch; char *s,*file; int count; - ii=razor_set_create_install_iterator(system,next); - printf("Running Transaction\n"); + razor_install_iterator_rewind(ii); + switch(stage) + { + case RAZOR_STAGE_SCRIPTS_PRE: + printf("Running pre-transaction scripts\n"); + break; + case RAZOR_STAGE_FILES: + printf("Running Transaction\n"); + break; + case RAZOR_STAGE_SCRIPTS_POST: + printf("Running post-transaction scripts\n"); + break; + default: + /* Keep the compiler happy */ + break; + } while (razor_install_iterator_next(ii,&package,&action,&count)) { if (action==RAZOR_INSTALL_ACTION_REMOVE) { razor_package_get_details(system,package,RAZOR_DETAIL_NAME,&name, RAZOR_DETAIL_LAST); - printf(" Removing : %s ",name); - if (razor_package_remove(system,next,package,install_root,count)<0) - printf( - "\nWarning: one or more errors occurred while removing %s", - name); - printf("\n"); + if (stage==RAZOR_STAGE_FILES) + printf(" Removing : %s ",name); + razor_package_remove(system,next,atomic,package,install_root, + count,stage); + if (stage==RAZOR_STAGE_FILES) + printf("\n"); } else { razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name, RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch, RAZOR_DETAIL_LAST); - printf(" Installing : %s ",name); s=rpm_filename(name,version,arch); file=plover_strconcat(base,"/rpms/",s,NULL); free(s); - rpm=razor_rpm_open(file); + rpm=razor_rpm_open(file,atomic); + free(file); if (!rpm) - { - fprintf(stderr,"failed to open rpm %s\n",file); - free(file); - razor_install_iterator_destroy(ii); return -1; - } + if (stage==RAZOR_STAGE_FILES) + printf(" Installing : %s ",name); if (relocations) razor_rpm_set_relocations(rpm,relocations); razor_transaction_fixup_package(trans,package,rpm); - if (razor_rpm_install(rpm,install_root,1)<0) - { - fprintf(stderr,"failed to install rpm %s\n",file); - razor_rpm_close(rpm); - free(file); - razor_install_iterator_destroy(ii); - return -1; - } + razor_rpm_install(rpm,atomic,install_root,1,stage); razor_rpm_close(rpm); - free(file); - printf("\n"); + if (stage==RAZOR_STAGE_FILES) + printf("\n"); } + if (razor_atomic_in_error_state(atomic)) + return -1; } - razor_install_iterator_destroy(ii); return 0; } +/* + * Note: plover_commit_transaction() takes ownership of root which should + * not be used after it returns. + */ +int plover_commit_transaction(struct razor_transaction *trans,const char *base, + const char *install_root,struct razor_root *root,struct razor_atomic *atomic, + struct razor_relocations *relocations) +{ + int retval; + struct razor_set *next,*system; + struct razor_install_iterator *ii; + razor_transaction_resolve(trans); + if (razor_transaction_describe(trans)>0) + { + razor_root_close(root); + return -1; + } + next=razor_transaction_commit(trans); + system=razor_root_get_system_set(root); + ii=razor_set_create_install_iterator(system,next); + plover_run_transaction(trans,ii,base,install_root,system,next,atomic, + relocations,RAZOR_STAGE_SCRIPTS_PRE); + plover_run_transaction(trans,ii,base,install_root,system,next,atomic, + relocations,RAZOR_STAGE_FILES); + razor_root_update(root,next); + razor_root_commit(root); + retval=razor_atomic_commit(atomic); + if (!retval) + plover_run_transaction(trans,ii,base,install_root,system,next,atomic, + relocations,RAZOR_STAGE_SCRIPTS_POST); + razor_set_unref(next); + razor_install_iterator_destroy(ii); + return retval; +} + static int plover_mark_package_for_update(struct razor_transaction *trans, struct razor_set *set,const char *pkg) { @@ -180,13 +223,14 @@ static int plover_mark_package_for_update(struct razor_transaction *trans, int plover_install(const char *base,const char *prefix,char **pkgs) { - int i; + int i,retval; char *s; char *install_root; struct razor_root *root; - struct razor_set *system,*set,*upstream,*next; + struct razor_set *system,*set,*upstream; struct razor_transaction *trans; struct razor_relocations *relocations; + struct razor_atomic *atomic; install_root=getenv("RAZOR_ROOT"); if (!install_root) install_root=""; @@ -195,82 +239,110 @@ int plover_install(const char *base,const char *prefix,char **pkgs) relocations=razor_relocations_create(); razor_relocations_add(relocations,"/usr",prefix); } + else + relocations=NULL; + atomic=razor_atomic_open("Install packages"); /* * Calling razor_root_open() on a system that hasn't yet had * razor_root_create() run generates a confusing error message * on stderr. Avoid this by trying to open it R/O first which * fails without generating any error. */ - set=razor_root_open_read_only(install_root); + set=razor_root_open_read_only(install_root,atomic); if (set) - razor_set_destroy(set); + razor_set_unref(set); else razor_root_create(install_root); - root=razor_root_open(install_root); + root=razor_root_open(install_root,atomic); if (!root) + { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; + } system=razor_root_get_system_set(root); if (!system) { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; } s=plover_strconcat(base,"/repodata",NULL); - if (!s) + if (s) { - razor_root_close(root); - return -1; + retval=chdir(s); + if (retval<0) + perror(s); } - if (chdir(s)<0) + else + retval=-1; + free(s); + if (retval<0) { - perror(s); - free(s); + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; } - free(s); set=plover_razor_set_create_from_yum(base); - if (!set) + if (set) + { + upstream=plover_relocate_packages(set,atomic,base,relocations); + razor_set_unref(set); + } + else + upstream=NULL; + if (!upstream) { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; } - upstream=plover_relocate_packages(set,base,relocations); - razor_set_destroy(set); trans=razor_transaction_create(system,upstream); + razor_set_unref(upstream); for(i=0;pkgs[i];i++) if (plover_mark_package_for_update(trans,system,pkgs[i]) && plover_mark_package_for_update(trans,upstream,pkgs[i])) { fprintf(stderr,"%s: Package not found\n",pkgs[i]); - razor_root_close(root); - return -1; + retval=-1; + break; } - razor_transaction_resolve(trans); - if (razor_transaction_describe(trans)>0) + if (!retval) { - razor_root_close(root); - return -1; + retval=plover_commit_transaction(trans,base,install_root,root,atomic, + relocations); + if (retval) + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); } - next=razor_transaction_commit(trans); - plover_run_transaction(trans,base,install_root,system,next,relocations); - razor_root_update(root,next); + else + razor_root_close(root); razor_transaction_destroy(trans); - razor_set_destroy(next); - razor_set_destroy(upstream); - if (prefix) + razor_atomic_destroy(atomic); + if (relocations) razor_relocations_destroy(relocations); - return razor_root_commit(root); + return retval; } int plover_update(const char *base,const char *prefix,char **pkgs) { - int i; + int i,retval; char *install_root,*s; struct razor_root *root; - struct razor_set *system,*set,*upstream,*next; + struct razor_set *system,*set,*upstream; struct razor_transaction *trans; struct razor_relocations *relocations; + struct razor_atomic *atomic; install_root=getenv("RAZOR_ROOT"); if (!install_root) install_root=""; @@ -279,73 +351,101 @@ int plover_update(const char *base,const char *prefix,char **pkgs) relocations=razor_relocations_create(); razor_relocations_add(relocations,"/usr",prefix); } - set=razor_root_open_read_only(install_root); + else + relocations=NULL; + atomic=razor_atomic_open("Update packages"); + set=razor_root_open_read_only(install_root,atomic); if (!set) + { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return 0; - razor_set_destroy(set); - root=razor_root_open(install_root); + } + razor_set_unref(set); + root=razor_root_open(install_root,atomic); if (!root) + { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; + } system=razor_root_get_system_set(root); if (!system) { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; } s=plover_strconcat(base,"/repodata",NULL); - if (!s) + if (s) { - razor_root_close(root); - return -1; + retval=chdir(s); + if (retval) + perror(s); } - if (chdir(s)<0) + else + retval=-1; + free(s); + if (retval) { - perror(s); - free(s); + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; } - free(s); set=plover_razor_set_create_from_yum(base); - if (!set) + if (set) + { + upstream=plover_relocate_packages(set,atomic,base,relocations); + razor_set_unref(set); + } + else + upstream=NULL; + if (!upstream) { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); + if (relocations) + razor_relocations_destroy(relocations); return -1; } - upstream=plover_relocate_packages(set,base,relocations); - razor_set_destroy(set); trans=razor_transaction_create(system,upstream); + razor_set_unref(upstream); if (pkgs) for(i=0;pkgs[i];i++) { if (plover_mark_package_for_update(trans,system,pkgs[i])) { fprintf(stderr,"%s: Package not found\n",pkgs[i]); - razor_transaction_destroy(trans); - razor_set_destroy(upstream); - razor_set_destroy(system); - razor_root_close(root); - return -1; + retval=-1; + break; } } else razor_transaction_update_all(trans); - razor_transaction_resolve(trans); - if (razor_transaction_describe(trans)>0) - { - razor_transaction_destroy(trans); - razor_set_destroy(upstream); - razor_set_destroy(system); - razor_root_close(root); - return -1; + if (!retval) { + retval=plover_commit_transaction(trans,base,install_root,root,atomic, + relocations); + if (retval) + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); } - next=razor_transaction_commit(trans); - plover_run_transaction(trans,base,install_root,system,next,relocations); - razor_root_update(root,next); + else + razor_root_close(root); razor_transaction_destroy(trans); - razor_set_destroy(next); - razor_set_destroy(upstream); - return razor_root_commit(root); + if (relocations) + razor_relocations_destroy(relocations); + razor_atomic_destroy(atomic); + return retval; } static int plover_mark_packages_for_removal(struct razor_transaction *trans, @@ -371,58 +471,108 @@ static int plover_mark_packages_for_removal(struct razor_transaction *trans, int plover_remove(char **pkgs) { - int i; + int i,retval=0; char *install_root; struct razor_root *root; - struct razor_set *system,*set,*upstream,*next; + struct razor_set *system,*set,*upstream; struct razor_transaction *trans; + struct razor_atomic *atomic; install_root=getenv("RAZOR_ROOT"); if (!install_root) install_root=""; - set=razor_root_open_read_only(install_root); + atomic=razor_atomic_open("Remove packages"); + set=razor_root_open_read_only(install_root,atomic); if (!set) + { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); return 0; - razor_set_destroy(set); - root=razor_root_open(install_root); + } + razor_set_unref(set); + root=razor_root_open(install_root,atomic); if (!root) + { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); return -1; + } system=razor_root_get_system_set(root); if (!system) { + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); razor_root_close(root); + razor_atomic_destroy(atomic); return -1; } upstream=razor_set_create_without_root(); trans=razor_transaction_create(system,upstream); + razor_set_unref(upstream); if (pkgs) for(i=0;pkgs[i];i++) { if (plover_mark_packages_for_removal(trans,system,pkgs[i])) { fprintf(stderr,"%s: Package not found\n",pkgs[i]); - razor_transaction_destroy(trans); - razor_set_destroy(upstream); - razor_set_destroy(system); - razor_root_close(root); - return -1; + retval=-1; + break; } } else plover_mark_packages_for_removal(trans,system,NULL); - razor_transaction_resolve(trans); - if (razor_transaction_describe(trans)>0) + if (!retval) { - razor_transaction_destroy(trans); - razor_set_destroy(upstream); - razor_set_destroy(system); - razor_root_close(root); - return -1; + retval= + plover_commit_transaction(trans,NULL,install_root,root,atomic,NULL); + if (retval) + fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic)); } - next=razor_transaction_commit(trans); - plover_run_transaction(trans,NULL,install_root,system,next,NULL); - razor_root_update(root,next); + else + razor_root_close(root); razor_transaction_destroy(trans); - razor_set_destroy(next); - razor_set_destroy(upstream); - return razor_root_commit(root); + razor_atomic_destroy(atomic); + return retval; +} + +/* + * Note: If there are no installed files, then any prefix will match. + */ + +int plover_installed_files_match_prefix(const char *prefix) +{ + int len,matches=1; + const char *name; + char *install_root; + struct razor_set *set; + struct razor_atomic *atomic; + struct razor_package *package; + struct razor_package_iterator *pi; + struct razor_file_iterator *fi; + len=strlen(prefix); + while(len && prefix[len-1]=='/') + len--; + install_root=getenv("RAZOR_ROOT"); + if (!install_root) + install_root=""; + atomic=razor_atomic_open("Query packages"); + set=razor_root_open_read_only(install_root,atomic); + if (set) + { + pi=razor_package_iterator_create(set); + while (matches && + razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST)) + { + fi=razor_file_iterator_create(set,package,0); + while (matches && razor_file_iterator_next(fi,&name)) + { + if (strncmp(name,prefix,len) || + name[len]!='\0' && name[len]!='/') + matches=0; + } + razor_file_iterator_destroy(fi); + } + razor_package_iterator_destroy(pi); + razor_set_unref(set); + } + razor_atomic_destroy(atomic); + return matches; } diff --git a/plover/util.c b/plover/util.c index 989ad99..6a65e55 100644 --- a/plover/util.c +++ b/plover/util.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 J. Ali Harlow + * Copyright (C) 2009, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,10 +60,30 @@ char *plover_strconcat(const char *string,...) char *plover_default_prefix_for_vendor(const char *vendor) { #ifdef WIN32 - char path[PATH_MAX]; - SHGetFolderPath(NULL,CSIDL_PROGRAM_FILES|CSIDL_FLAG_DONT_VERIFY,NULL,0, - path); - return plover_strconcat(path,"\\",vendor?vendor:"Plover",NULL); + /* + * We want to sidestep any redirecting that MS-Windows may + * introduce since this will be based on the architecture + * of the installer whereas the architecture that actually + * matters is of the packages (checked elsewhere). + */ + BOOL is_wow64=FALSE; + typedef BOOL (WINAPI *is_wow64_process_t)(HANDLE,PBOOL); + is_wow64_process_t is_wow64_process; + char *program_files=NULL; + char buf[PATH_MAX]; + is_wow64_process=(is_wow64_process_t) + GetProcAddress(GetModuleHandleA("kernel32"),"IsWow64Process"); + if (is_wow64_process) + is_wow64_process(GetCurrentProcess(),&is_wow64); + if (is_wow64) + program_files=getenv("ProgramW6432"); + if (!program_files) + { + SHGetFolderPath(NULL,CSIDL_PROGRAM_FILES|CSIDL_FLAG_DONT_VERIFY,NULL,0, + buf); + program_files=buf; + } + return plover_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL); #else return NULL; #endif diff --git a/setup/Makefile.am b/setup/Makefile.am index f1c4d68..a1e148b 100644 --- a/setup/Makefile.am +++ b/setup/Makefile.am @@ -7,13 +7,13 @@ bin_PROGRAMS=setup setup_SOURCES=setup.c setup_LDFLAGS=-all-static if HAVE_WINDRES -setup_SOURCES+=resources.rc +setup_SOURCES+=resources.rc setup.exe.manifest endif .png.pnm: pngtopnm $< | pnmquant 256 > $@ -resources.$(OBJEXT): resources.rc setup.ico +resources.$(OBJEXT): resources.rc setup.exe.manifest setup.ico $(WINDRES) resources.rc $@ setup.ico: icon16.pnm icon22.pnm icon32.pnm diff --git a/setup/manifest.xml.in b/setup/manifest.xml.in new file mode 100644 index 0000000..65d4b3a --- /dev/null +++ b/setup/manifest.xml.in @@ -0,0 +1,22 @@ +changequote([,])dnl + + + + Plover setup program + + + + + + + + + + + + + + diff --git a/setup/resources.rc.in b/setup/resources.rc.in index 895d9f7..edf67c0 100644 --- a/setup/resources.rc.in +++ b/setup/resources.rc.in @@ -1,4 +1,5 @@ #include +#include MAINICON ICON "setup.ico" @@ -19,7 +20,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "FileVersion","@PACKAGE_VERSION@" VALUE "InternalName","setup" VALUE "LegalCopyright", - "Copyright (c) 2009 J. Ali Harlow et al" + "Copyright (c) 2009,2011 J. Ali Harlow et al" VALUE "OriginalFilename","setup.exe" VALUE "ProductName","plover" VALUE "ProductVersion","@PACKAGE_VERSION@" @@ -30,3 +31,5 @@ VS_VERSION_INFO VERSIONINFO VALUE "Translation",0x809,0x4B0 } } + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "setup.exe.manifest" diff --git a/setup/setup.c b/setup/setup.c index 05b443c..c6cf79e 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 J. Ali Harlow + * Copyright (C) 2009, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -75,21 +75,10 @@ void vector_free(struct vector *vector) free(vector); } -static void *alloc_lua(void *user_data,void *ptr,size_t osize,size_t nsize) -{ - if (!nsize) - { - free(ptr); - return NULL; - } - else - return realloc(ptr,nsize); -} - void setup(const char *argv0) { char *path,*s,*prefix; - int changed; + int ch,changed; struct comps *comps; struct comps_group *group; struct comps_requirement *pkg; @@ -104,6 +93,18 @@ void setup(const char *argv0) } free(s); prefix=plover_default_prefix_for_vendor(comps->vendor); + if (!plover_installed_files_match_prefix(prefix)) + { + printf("The existing installation is not under %s\n" + "In order to continue, all the existing packages must be removed.\n" + "Do you want to remove all existing packages? ",prefix); + ch=getchar(); + if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n') + exit(1); + while(ch!='\n' && ch!=EOF) + ch=getchar(); + plover_remove(NULL); + } group=plover_comps_lookup_group(comps,"base"); if (!group) { @@ -148,4 +149,5 @@ int main(int argc,char **argv) plover_remove(NULL); else setup(argv[0]); + exit(0); } diff --git a/update/Makefile.am b/update/Makefile.am index 0f721c2..bd8b841 100644 --- a/update/Makefile.am +++ b/update/Makefile.am @@ -7,13 +7,13 @@ bin_PROGRAMS=update update_SOURCES=update.c update_LDFLAGS=-all-static if HAVE_WINDRES -update_SOURCES+=resources.rc +update_SOURCES+=resources.rc update.exe.manifest endif .png.pnm: pngtopnm $< | pnmquant 256 > $@ -resources.$(OBJEXT): resources.rc update.ico +resources.$(OBJEXT): resources.rc update.exe.manifest update.ico $(WINDRES) resources.rc $@ update.ico: icon16.pnm icon22.pnm icon32.pnm diff --git a/update/manifest.xml.in b/update/manifest.xml.in new file mode 100644 index 0000000..d0fe4bc --- /dev/null +++ b/update/manifest.xml.in @@ -0,0 +1,22 @@ +changequote([,])dnl + + + + Plover update program + + + + + + + + + + + + + + diff --git a/update/resources.rc.in b/update/resources.rc.in index b11aecb..9313b10 100644 --- a/update/resources.rc.in +++ b/update/resources.rc.in @@ -1,4 +1,5 @@ #include +#include MAINICON ICON "update.ico" @@ -15,11 +16,11 @@ VS_VERSION_INFO VERSIONINFO BLOCK "080904B0" { VALUE "CompanyName","The plover development team" - VALUE "FileDescription","Plover setup program" + VALUE "FileDescription","Plover update program" VALUE "FileVersion","@PACKAGE_VERSION@" VALUE "InternalName","update" VALUE "LegalCopyright", - "Copyright (c) 2009 J. Ali Harlow et al" + "Copyright (c) 2009,2011 J. Ali Harlow et al" VALUE "OriginalFilename","update.exe" VALUE "ProductName","plover" VALUE "ProductVersion","@PACKAGE_VERSION@" @@ -30,3 +31,5 @@ VS_VERSION_INFO VERSIONINFO VALUE "Translation",0x809,0x4B0 } } + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update.exe.manifest" diff --git a/update/update.c b/update/update.c index 13fc828..4127239 100644 --- a/update/update.c +++ b/update/update.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 J. Ali Harlow + * Copyright (C) 2009, 2011 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,7 @@ */ #include +#include #include #include "config.h" #include "plover/plover.h" @@ -27,6 +28,7 @@ LUALIB_API int luaopen_posix(lua_State *L); void update(const char *argv0) { char *path,*s,*prefix; + int ch; struct comps *comps; path=plover_get_program_directory(argv0); s=plover_strconcat(path,"/repodata/comps.xml",NULL); @@ -38,6 +40,18 @@ void update(const char *argv0) } free(s); prefix=plover_default_prefix_for_vendor(comps->vendor); + if (!plover_installed_files_match_prefix(prefix)) + { + printf("The existing installation is not under %s\n" + "In order to continue, all the existing packages must be removed.\n" + "Do you want to remove all existing packages? ",prefix); + ch=getchar(); + if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n') + exit(1); + while(ch!='\n' && ch!=EOF) + ch=getchar(); + plover_remove(NULL); + } plover_comps_free(comps); plover_update(path,prefix,NULL); free(prefix); @@ -49,4 +63,5 @@ int main(int argc,char **argv) razor_set_lua_loader("posix",luaopen_posix); razor_set_lua_loader("whelk",luaopen_whelk); update(argv[0]); + exit(0); }