# HG changeset patch # User J. Ali Harlow # Date 1468663638 -3600 # Node ID 31fb3572762175b0787a0980b7d85d0dbb2d3a5e # Parent 772ff096a326737ce39c47966ef4e4c1427b861e Support parallel installations. The idea is that for CAD screener, we want to be able to install this on the same machine as a standard AVOT setup (most notably for John's laptop). To allow for the possibility of a second application that might have the same requirements, we add the concept of vendor-specific distributions. Thus we can have one distribution for CAD screener and one for The Next Big Thing. It doesn't seem trivial to have both CAD screener and AVOT under the same vendor tag so we'll have to have AVOT under "City Occupational" and CAD screener under "City Occupational Ltd" or some such kludge. Most of this is done although we are very short of test cases (in particular we don't test that it's actually possible to install CAD screener in parallel with AVOT or to update either of them once installed, which is fundamental). We also have a lot of baggage left over, including an intercept of razor_set. The problem that this was introduced to debug has been fixed but it looks like there are a number of memory leaks which it might be useful to help track down so it has been left in place for now. There is still a lot of confusion in plover between path-based and URI-based API. We should review the API, decide what we want and have a general clear up. There is also confusion as to the purpose of RAZOR_ROOT (and meaning; path or URI). This is not used at all in librazor (although it is used in razor.exe). Ideally we shouldn't use it in plover or plover-gtk either although again, we might want to support it or an equivalent in (some of) the various executables. Work that would still to nice to do for CAD screener: - uninstall (ideally as an installed program that hooks into Add/Remove programs but even re-running the installer would be acceptable). - xz support (smaller packages). - repomd.xml and xml:base (would be needed for an Internet installer). - graphical installer. diff -r 772ff096a326 -r 31fb35727621 app-manager/app-manager.c --- a/app-manager/app-manager.c Fri Jul 08 08:33:44 2016 +0100 +++ b/app-manager/app-manager.c Sat Jul 16 11:07:18 2016 +0100 @@ -215,17 +215,20 @@ { GError *err=0; GtkWidget *w; - gchar *s,*contents; - gchar *setup_base=NULL,*update_base=NULL; + gchar *s,*database_uri,*contents; + gchar *database=NULL,*setup_base=NULL,*update_base=NULL; gsize len; - PloverPackageSet *set; + struct comps *comps; + PloverPackageSet *set=NULL; GSList *objects,*lnk; gboolean started; GOptionEntry options[]={ - {"setup",0,0,G_OPTION_ARG_FILENAME,&setup_base, - "Setup from installation media","path"}, - {"update",0,0,G_OPTION_ARG_FILENAME,&update_base, - "Update from upgrade media","path"}, + {"database",0,0,G_OPTION_ARG_STRING,&database, + "Operate on a distribution-local database","vendor/distribution"}, + {"setup",0,0,G_OPTION_ARG_STRING,&setup_base, + "Setup from installation media","uri"}, + {"update",0,0,G_OPTION_ARG_STRING,&update_base, + "Update from upgrade media","uri"}, {NULL} }; #ifdef WIN32 @@ -285,30 +288,52 @@ g_error("%s",err->message); exit(0); } - if (prefix) - { - relocations=razor_relocations_create(); - razor_relocations_add(relocations,"/usr",prefix); - } gtk_builder_connect_signals(ui,NULL); gtk_link_button_set_uri_hook(show_uri,NULL,NULL); - installed=GTK_TREE_MODEL(plover_package_store_new()); - set=plover_package_set_new(); - (void)plover_package_set_open(set,"",TRUE,NULL); - plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set); - if (plover_package_set_get_no_details(set)) - { - w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles")); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE); - } - applications=plover_applications_model_new(installed); - set_package_model(applications); if (setup_base) - started=setup(set,setup_base); + started=setup(setup_base); else if (update_base) - started=update(set,update_base); + started=update(update_base); else { + if (database) + { + g_free(prefix); + prefix=NULL; + s=strchr(database,'/'); + if (*s) + *s++='\0'; + comps=plover_comps_new(); + plover_comps_set_vendor(comps,database); + if (s) + { + plover_comps_set_distribution(comps,s); + *--s='/'; + } + prefix=plover_comps_get_default_prefix(comps); + plover_comps_free(comps); + s=g_strconcat(prefix,"/var/lib/razor",NULL); + database_uri=razor_path_to_uri(s); + g_free(s); + razor_set_database_uri(database_uri); + g_free(database_uri); + } + if (prefix) + { + relocations=razor_relocations_create(); + razor_relocations_add(relocations,"/usr",prefix); + } + installed=GTK_TREE_MODEL(plover_package_store_new()); + set=plover_package_set_new(); + (void)plover_package_set_open(set,"",TRUE,NULL); + plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set); + if (plover_package_set_get_no_details(set)) + { + w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles")); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE); + } + applications=plover_applications_model_new(installed); + set_package_model(applications); w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow")); gtk_widget_show(w); started=TRUE; @@ -332,6 +357,7 @@ g_free(prefix); g_free(setup_base); g_free(update_base); + g_free(database); exit(0); } diff -r 772ff096a326 -r 31fb35727621 app-manager/app-manager.h --- a/app-manager/app-manager.h Fri Jul 08 08:33:44 2016 +0100 +++ b/app-manager/app-manager.h Sat Jul 16 11:07:18 2016 +0100 @@ -7,5 +7,5 @@ GtkTreeModel *plover_applications_model_new(GtkTreeModel *installed); void set_package_model(GtkTreeModel *model); PloverPackage *get_active_package(void); -gboolean setup(PloverPackageSet *current,const char *base); -gboolean update(PloverPackageSet *current,const char *base); +gboolean setup(const char *base); +gboolean update(const char *base); diff -r 772ff096a326 -r 31fb35727621 app-manager/setup.c --- a/app-manager/setup.c Fri Jul 08 08:33:44 2016 +0100 +++ b/app-manager/setup.c Sat Jul 16 11:07:18 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 J. Ali Harlow + * Copyright (C) 2014, 2016 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 @@ -29,7 +29,7 @@ #include #include "app-manager.h" -gboolean setup(PloverPackageSet *installed,const char *base) +gboolean setup(const char *base) { gchar *s; const char *prefix; @@ -38,7 +38,6 @@ if (!helper) { helper=plover_transaction_helper_new(ui); - plover_transaction_helper_set_installed(helper,installed); plover_transaction_helper_set_base(helper,base); prefix=plover_transaction_helper_get_prefix(helper,&error); if (error) diff -r 772ff096a326 -r 31fb35727621 app-manager/update.c --- a/app-manager/update.c Fri Jul 08 08:33:44 2016 +0100 +++ b/app-manager/update.c Sat Jul 16 11:07:18 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 J. Ali Harlow + * Copyright (C) 2014, 2016 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 @@ -29,16 +29,16 @@ #include #include "app-manager.h" -gboolean update(PloverPackageSet *installed,const char *base) + +gboolean update(const char *base) { - gchar *s; + gchar *s,*database_uri; const char *prefix; GError *error=NULL; static PloverTransactionHelper *helper=NULL; if (!helper) { helper=plover_transaction_helper_new(ui); - plover_transaction_helper_set_installed(helper,installed); plover_transaction_helper_set_base(helper,base); prefix=plover_transaction_helper_get_prefix(helper,&error); if (error) diff -r 772ff096a326 -r 31fb35727621 configure.ac --- a/configure.ac Fri Jul 08 08:33:44 2016 +0100 +++ b/configure.ac Sat Jul 16 11:07:18 2016 +0100 @@ -15,8 +15,7 @@ setup/Makefile setup/resources.rc update/Makefile -update/update-res.rc -update/updatez-res.rc +update/resources.rc pre-inst/Makefile pre-inst/resources.rc app-manager/Makefile @@ -28,8 +27,7 @@ tests/plover-gtk/Makefile ]) PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in -update/update.exe.manifest:update/update.manifest.in -update/updatez.exe.manifest:update/updatez.manifest.in +update/update.exe.manifest:update/manifest.xml.in pre-inst/pre-inst.exe.manifest:pre-inst/manifest.xml.in app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in plover-open/plover-open.exe.manifest:plover-open/manifest.xml.in diff -r 772ff096a326 -r 31fb35727621 plover-gtk/transactionhelper.c --- a/plover-gtk/transactionhelper.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover-gtk/transactionhelper.c Sat Jul 16 11:07:18 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 J. Ali Harlow + * Copyright (C) 2014, 2016 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 @@ -18,6 +18,7 @@ #include "config.h" #include +#include #include #include #include @@ -88,6 +89,7 @@ g_slist_foreach(helper->transactions,(GFunc)g_object_unref,NULL); g_slist_free(helper->transactions); helper->transactions=NULL; + g_clear_object(&helper->alternate_installed); g_clear_object(&helper->installed); g_clear_object(&helper->upstream); g_clear_object(&helper->relocated_upstream); @@ -458,7 +460,92 @@ PloverPackageSet * plover_transaction_helper_get_installed(PloverTransactionHelper *helper) { + gchar *s,*saved_database_uri; + char *install_root,*local_database,*active_database,*alternate_database; + const char *prefix; + struct comps *comps; + PloverPackageSet *alternate_installed,*installed; + GError *error=NULL; + struct razor_error *razor_error=NULL; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); + if (!helper->installed) + { + comps=plover_transaction_helper_get_comps(helper,NULL); + if (!comps) + { + g_warning("plover_transaction_helper_get_installed: No comps"); + return NULL; + } + install_root=getenv("RAZOR_ROOT"); + if (!install_root) + install_root="file:/"; + prefix=plover_transaction_helper_get_prefix(helper,NULL); + if (prefix) + { + s=g_strconcat(prefix,"/var/lib/razor",NULL); + local_database=razor_path_relative_to_uri(install_root,*s=='/'?s+1:s, + &razor_error); + g_free(s); + if (!local_database) + { + g_warning("plover_transaction_helper_get_installed: %s", + razor_error_get_msg(razor_error)); + razor_error_free(razor_error); + return NULL; + } + } + else + local_database=NULL; + switch(comps->database) + { + case COMPS_DATABASE_DISTRIBUTION_LOCAL: + active_database=local_database; + alternate_database=NULL; + break; + case COMPS_DATABASE_GLOBAL: + active_database=NULL; + alternate_database=local_database; + break; + } + saved_database_uri=g_strdup(razor_get_database_uri()); + if (prefix) + { + razor_set_database_uri(alternate_database); + alternate_installed=plover_package_set_new(); + if (!plover_package_set_open(alternate_installed,install_root,TRUE, + &error)) + { + g_object_unref(alternate_installed); + g_warning("plover_transaction_helper_get_installed: %s", + error->message); + g_error_free(error); + free(local_database); + razor_set_database_uri(saved_database_uri); + g_free(saved_database_uri); + return NULL; + } + } + else + alternate_installed=NULL; + razor_set_database_uri(active_database); + free(local_database); + installed=plover_package_set_new(); + if (plover_package_set_open(installed,install_root,TRUE,&error)) + { + helper->alternate_installed=alternate_installed; + helper->installed=installed; + } + else + { + g_object_unref(installed); + if (alternate_installed) + g_object_unref(alternate_installed); + g_warning("plover_transaction_helper_get_installed: %s",error->message); + g_error_free(error); + } + razor_set_database_uri(saved_database_uri); + g_free(saved_database_uri); + } return helper->installed; } @@ -468,6 +555,7 @@ g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper)); g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed)); g_return_if_fail(helper->installed == NULL); + g_clear_object(&helper->alternate_installed); helper->installed=g_object_ref(installed); } @@ -536,7 +624,7 @@ struct comps *comps; PloverTransactionHelperPrivate *priv; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); - g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL); + g_return_val_if_fail(helper->base != NULL || plover_transaction_helper_get_installed(helper) != NULL,NULL); priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); if (helper->base) { @@ -544,13 +632,14 @@ if (!comps) return NULL; g_free(priv->default_prefix); - priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor); + priv->default_prefix=plover_comps_get_default_prefix(comps); return priv->default_prefix; } prefix=plover_package_set_guess_prefix(helper->installed,error); return prefix; } +#if 0 static int plover_transaction_helper_package_count(void) { int count=0; @@ -572,44 +661,84 @@ } return count; } +#endif + +static gboolean prefix_clashes(const char *prefix,const char *alt) +{ + return g_str_has_prefix(prefix,alt) && + (prefix[strlen(alt)]=='\0' || prefix[strlen(alt)]=='/'); +} static gboolean plover_transaction_helper_check_vendor(PloverTransactionHelper *helper, GError **error) { - int i; + int i,remove_count=0; + gboolean alternate_database_clashes=FALSE; + gboolean active_database_is_incompatible=FALSE; + char *local_database,*active_database,*alternate_database; + const char *alternate_prefix; gchar *prefix=NULL,*s; struct comps *comps=NULL; GtkWidget *container,*summary,*page; GtkButton *button; GtkLabel *label; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); - if (helper->check_vendor) - { - comps=plover_transaction_helper_get_comps(helper,error); - if (!comps) - return FALSE; - prefix=plover_default_prefix_for_vendor(comps->vendor); - } + comps=plover_transaction_helper_get_comps(helper,error); + if (!comps) + return FALSE; + prefix=plover_comps_get_default_prefix(comps); button=GTK_BUTTON(gtk_builder_get_object(helper->ui,"SIRemoveExisting")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE); container=GTK_WIDGET(gtk_builder_get_object(helper->ui, "SIIncompatibleInstallation")); summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork")); page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm")); - if (helper->check_vendor && prefix && - !plover_installed_files_match_prefix(prefix)) + if (helper->check_vendor && prefix && helper->alternate_installed) + { + alternate_prefix= + plover_package_set_guess_prefix(helper->alternate_installed,NULL); + if (alternate_prefix && prefix_clashes(prefix,alternate_prefix)) + { + alternate_database_clashes=TRUE; + remove_count=g_slist_length( + plover_package_set_get_packages(helper->alternate_installed)); + } + } + /* + * Rather than try to be too clever, we only deal with one thing + * at a time. That means that if the alternate database clashes + * there's no point checking if the active database is compatible. + */ + if (!alternate_database_clashes) + { + if (helper->check_vendor && prefix && + !plover_package_set_files_match_prefix(helper->installed,prefix)) + { + active_database_is_incompatible=TRUE; + remove_count= + g_slist_length(plover_package_set_get_packages(helper->installed)); + } + } + if (alternate_database_clashes || active_database_is_incompatible) { label=GTK_LABEL(gtk_builder_get_object(helper->ui, "SIIncompatibleInstallationLabel")); - s=g_strdup_printf("Incompatible Installation\n\n" - "The existing installation is not from %s.\n" - "In order to continue, all the existing packages must be removed.", - comps->vendor); + if (alternate_database_clashes) + s=g_strdup_printf("Incompatible Installation\n\n" + "There is an existing installation under %s\n" + "which is not compatible with this distribution. In order\n" + "to continue, the existing installation must be uninstalled.", + comps->vendor); + else /* active_database_is_incompatible */ + s=g_strdup_printf("Incompatible Installation\n\n" + "The existing installation is not from %s.\n In order " + "to continue, all the existing packages must be removed.", + comps->vendor); gtk_label_set_markup(label,s); g_free(s); - i=plover_transaction_helper_package_count(); - s=g_strdup_printf("Remove %d existing package%s",i,i==1?"":"s"); + s=g_strdup_printf("Remove %d existing package%s",remove_count, + remove_count==1?"":"s"); gtk_button_set_label(button,s); g_free(s); gtk_widget_show(container); @@ -806,7 +935,7 @@ GError *tmp_error=NULL; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); - g_return_val_if_fail(helper->installed != NULL,NULL); + g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,NULL); prefix=plover_transaction_helper_get_prefix(helper,&tmp_error); if (tmp_error) { @@ -942,7 +1071,7 @@ struct plover_vector *selected_packages; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); - g_return_val_if_fail(helper->installed != NULL,FALSE); + g_return_val_if_fail(plover_transaction_helper_get_installed(helper) != NULL,FALSE); selected_packages=plover_transaction_helper_group_get_default_packages( helper,group,error); if (!selected_packages) diff -r 772ff096a326 -r 31fb35727621 plover-gtk/transactionhelper.h --- a/plover-gtk/transactionhelper.h Fri Jul 08 08:33:44 2016 +0100 +++ b/plover-gtk/transactionhelper.h Sat Jul 16 11:07:18 2016 +0100 @@ -33,7 +33,7 @@ typedef struct _PloverTransactionHelper { GObject parent_instance; - PloverPackageSet *installed; + PloverPackageSet *alternate_installed,*installed; PloverRepository *upstream; PloverPackageSet *relocated_upstream; gchar *base; diff -r 772ff096a326 -r 31fb35727621 plover/Makefile.am --- a/plover/Makefile.am Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/Makefile.am Sat Jul 16 11:07:18 2016 +0100 @@ -5,12 +5,13 @@ AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO) \ $(CODE_COVERAGE_LDFLAGS) -export-symbols-regex '^plover_[^_]' -pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h +pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h \ + inputstream.h lib_LTLIBRARIES=libplover.la libplover_la_SOURCES=$(pkginclude_HEADERS) util.c import-yum.c razor.c comps.c \ log.c vector.c transaction.c package.c packageset.c repository.c \ - uri-handler.c uri-handler.h exception-handler.cpp + uri-handler.c uri-handler.h inputstream.c exception-handler.cpp pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA=plover.pc diff -r 772ff096a326 -r 31fb35727621 plover/comps.c --- a/plover/comps.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/comps.c Sat Jul 16 11:07:18 2016 +0100 @@ -28,6 +28,8 @@ /* Parse a comps.xml package group file. */ +#define PLOVER_XML_NS "http://project.juiblex.co.uk/plover/ns/2009" + static struct comps_requirement *comps_package_requirement_new(void) { struct comps_requirement *req; @@ -104,6 +106,7 @@ if (comps) { free(comps->vendor); + free(comps->distribution); comps_group_free(comps->groups); free(comps); } @@ -126,7 +129,8 @@ XML_Parser parser; enum comps_state state; int unknown_elements; - char *vendor; + char *vendor,*distribution; + enum comps_database_setting database; struct comps_group *group; void *p; }; @@ -196,9 +200,17 @@ ctx->state=COMPS_STATE_ROOT; for (i=0;atts[i];i+=2) { - if (!strcmp(atts[i], - "http://project.juiblex.co.uk/plover/ns/2009\xFFvendor")) + if (!strcmp(atts[i],PLOVER_XML_NS "\xFF" "vendor")) ctx->vendor=strdup(atts[i+1]); + else if (!strcmp(atts[i],PLOVER_XML_NS "\xFF" "distribution")) + ctx->distribution=strdup(atts[i+1]); + else if (!strcmp(atts[i],PLOVER_XML_NS "\xFF" "database")) + { + if (!g_strcmp0(atts[i+1],"distribution-local")) + ctx->database=COMPS_DATABASE_DISTRIBUTION_LOCAL; + else + ctx->database=COMPS_DATABASE_GLOBAL; + } } } else if (ctx->state==COMPS_STATE_ROOT && !strcmp(name,"group")) @@ -371,64 +383,47 @@ } } -#define XML_BUFFER_SIZE 4096 - -struct comps *plover_comps_new_from_uri(const char *uri) +struct comps *plover_comps_new_from_uri(const char *uri,GError **error) { struct comps_context ctx={0}; - void *buf; - gssize len; - GFile *file; - GFileInputStream *stream; - XML_ParsingStatus status; + struct razor_error *tmp_error=NULL; + void *contents; + size_t length; struct comps *comps; plover__uri_handler_init(); - file=g_file_new_for_uri(uri); - stream=g_file_read(file,NULL,NULL); - g_object_unref(file); - if (!stream) + contents=razor_uri_get_contents(uri,&length,FALSE,&tmp_error); + if (!contents) + { + plover_propagate_razor_error(error,tmp_error); return NULL; + } ctx.state=COMPS_STATE_BEGIN; ctx.parser=XML_ParserCreateNS(NULL,'\xFF'); XML_SetUserData(ctx.parser,&ctx); XML_SetElementHandler(ctx.parser,comps_start_element,comps_end_element); XML_SetCharacterDataHandler(ctx.parser,comps_character_data); - do + if (XML_Parse(ctx.parser,contents,length,TRUE)==XML_STATUS_ERROR) { - XML_GetParsingStatus(ctx.parser,&status); - switch (status.parsing) - { - case XML_SUSPENDED: - XML_ResumeParser(ctx.parser); - break; - case XML_PARSING: - case XML_INITIALIZED: - buf=XML_GetBuffer(ctx.parser,XML_BUFFER_SIZE); - len=g_input_stream_read(G_INPUT_STREAM(stream),buf, - XML_BUFFER_SIZE,NULL,NULL); - if (len<0) - { - comps_group_free(ctx.group); - XML_ParserFree(ctx.parser); - g_object_unref(stream); - return NULL; - } - if (!XML_ParseBuffer(ctx.parser,len,!len)) - { - comps_group_free(ctx.group); - XML_ParserFree(ctx.parser); - g_object_unref(stream); - return NULL; - } - break; - case XML_FINISHED: - break; - } - } while (status.parsing!=XML_FINISHED); + g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED, + "%s on line %d of '%s'\n", + XML_ErrorString(XML_GetErrorCode(ctx.parser)), + XML_GetCurrentLineNumber(ctx.parser),uri); + XML_ParserFree(ctx.parser); + razor_uri_free_contents(contents,length); + return NULL; + } XML_ParserFree(ctx.parser); - g_object_unref(stream); + razor_uri_free_contents(contents,length); comps=plover_comps_new(); comps->vendor=ctx.vendor; + comps->distribution=ctx.distribution; + comps->database=ctx.database; + if (comps->database==COMPS_DATABASE_DISTRIBUTION_LOCAL && + (!comps->vendor || !comps->distribution)) + { + g_warning("%s: database setting of distribution-local ignored",uri); + comps->database=COMPS_DATABASE_GLOBAL; + } comps->groups=ctx.group; return comps; } @@ -441,7 +436,7 @@ file=g_file_new_for_path(filename); uri=g_file_get_uri(file); g_object_unref(file); - comps=plover_comps_new_from_uri(uri); + comps=plover_comps_new_from_uri(uri,NULL); g_free(uri); return comps; } @@ -455,3 +450,15 @@ return group; return NULL; } + +void plover_comps_set_vendor(struct comps *comps,const char *vendor) +{ + free(comps->vendor); + comps->vendor=strdup(vendor); +} + +void plover_comps_set_distribution(struct comps *comps,const char *distribution) +{ + free(comps->distribution); + comps->distribution=strdup(distribution); +} diff -r 772ff096a326 -r 31fb35727621 plover/import-yum.c --- a/plover/import-yum.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/import-yum.c Sat Jul 16 11:07:18 2016 +0100 @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc - * Copyright (C) 2009, 2011, 2014 J. Ali Harlow + * Copyright (C) 2009, 2011, 2014, 2016 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 @@ -34,6 +34,7 @@ #include #include "plover/plover.h" #include "plover/uri-handler.h" +#include "plover/inputstream.h" /* Import a yum filelist as a razor package set. */ @@ -337,7 +338,7 @@ void *buf; gssize len; GFile *file; - GFileInputStream *stream; + GInputStream *stream; GInputStream *primary,*filelists; GZlibDecompressor *decompressor; XML_ParsingStatus status; @@ -361,10 +362,8 @@ yum_filelists_end_element); XML_SetCharacterDataHandler(ctx.filelists_parser,yum_character_data); uri=razor_path_relative_to_uri(base_uri,"repodata/primary.xml.gz",NULL); - file=g_file_new_for_uri(uri); + stream=plover_razor_input_stream_new(uri,error); free(uri); - stream=g_file_read(file,NULL,error); - g_object_unref(file); if (!stream) { XML_ParserFree(ctx.primary_parser); XML_ParserFree(ctx.filelists_parser); @@ -376,11 +375,10 @@ g_object_unref(stream); g_object_unref(decompressor); uri=razor_path_relative_to_uri(base_uri,"repodata/filelists.xml.gz",NULL); - file=g_file_new_for_uri(uri); + stream=plover_razor_input_stream_new(uri,error); free(uri); - stream=g_file_read(file,NULL,error); - g_object_unref(file); if (!stream) { + g_object_unref(primary); XML_ParserFree(ctx.primary_parser); XML_ParserFree(ctx.filelists_parser); return NULL; diff -r 772ff096a326 -r 31fb35727621 plover/inputstream.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plover/inputstream.c Sat Jul 16 11:07:18 2016 +0100 @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2006-2007 Red Hat, Inc + * Copyright (C) 2016 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include "plover/inputstream.h" + +/** + * SECTION:ploverrazorinputstream + * @short_description: Streaming input operations on razor files + * @include: plover/inputstream.h + * @see_also: #GMemoryInputStream + * + * #PloverRazorInputStream provides input streams that get their + * content via razor's URI input routines. + */ + +struct _PloverRazorInputStreamPrivate +{ + void *buf; + gsize len; + gsize pos; +}; + +static gssize plover_razor_input_stream_read(GInputStream *stream,void *buffer, + gsize count,GCancellable *cancellable,GError **error); +static gssize plover_razor_input_stream_skip(GInputStream *stream,gsize count, + GCancellable *cancellable,GError **error); +static gboolean plover_razor_input_stream_close(GInputStream *stream, + GCancellable *cancellable,GError **error); +static void plover_razor_input_stream_skip_async(GInputStream *stream, + gsize count,int io_priority,GCancellable *cancellable, + GAsyncReadyCallback callback,gpointer data); +static gssize plover_razor_input_stream_skip_finish(GInputStream *stream, + GAsyncResult *result,GError **error); +static void plover_razor_input_stream_close_async(GInputStream *stream, + int io_priority,GCancellable *cancellable,GAsyncReadyCallback callback, + gpointer data); +static gboolean plover_razor_input_stream_close_finish(GInputStream *stream, + GAsyncResult *result,GError **error); +static void + plover_razor_input_stream_seekable_iface_init(GSeekableIface *iface); +static goffset plover_razor_input_stream_tell(GSeekable *seekable); +static gboolean plover_razor_input_stream_can_seek(GSeekable *seekable); +static gboolean plover_razor_input_stream_seek(GSeekable *seekable, + goffset offset,GSeekType type,GCancellable *cancellable,GError **error); +static gboolean plover_razor_input_stream_can_truncate(GSeekable *seekable); +static gboolean plover_razor_input_stream_truncate(GSeekable *seekable, + goffset offset,GCancellable *cancellable,GError **error); +static void plover_razor_input_stream_pollable_iface_init( + GPollableInputStreamInterface *iface); +static gboolean + plover_razor_input_stream_is_readable(GPollableInputStream *stream); +static GSource * + plover_razor_input_stream_create_source(GPollableInputStream *stream, + GCancellable *cancellable); +static void plover_razor_input_stream_finalize(GObject *object); + +G_DEFINE_TYPE_WITH_CODE(PloverRazorInputStream,plover_razor_input_stream, + G_TYPE_INPUT_STREAM, + G_IMPLEMENT_INTERFACE(G_TYPE_SEEKABLE, + plover_razor_input_stream_seekable_iface_init); + G_IMPLEMENT_INTERFACE(G_TYPE_POLLABLE_INPUT_STREAM, + plover_razor_input_stream_pollable_iface_init); +) + +static void + plover_razor_input_stream_class_init(PloverRazorInputStreamClass *klass) +{ + GObjectClass *object_class; + GInputStreamClass *istream_class; + g_type_class_add_private(klass,sizeof(PloverRazorInputStreamPrivate)); + object_class=G_OBJECT_CLASS(klass); + object_class->finalize=plover_razor_input_stream_finalize; + istream_class=G_INPUT_STREAM_CLASS(klass); + istream_class->read_fn=plover_razor_input_stream_read; + istream_class->skip=plover_razor_input_stream_skip; + istream_class->close_fn=plover_razor_input_stream_close; + istream_class->skip_async=plover_razor_input_stream_skip_async; + istream_class->skip_finish=plover_razor_input_stream_skip_finish; + istream_class->close_async=plover_razor_input_stream_close_async; + istream_class->close_finish=plover_razor_input_stream_close_finish; +} + +static void plover_razor_input_stream_finalize(GObject *object) +{ + PloverRazorInputStream *razor_stream; + PloverRazorInputStreamPrivate *priv; + razor_stream=PLOVER_RAZOR_INPUT_STREAM(object); + priv=razor_stream->priv; + razor_uri_free_contents(priv->buf,priv->len); + G_OBJECT_CLASS(plover_razor_input_stream_parent_class)->finalize(object); +} + +static void plover_razor_input_stream_seekable_iface_init(GSeekableIface *iface) +{ + iface->tell=plover_razor_input_stream_tell; + iface->can_seek=plover_razor_input_stream_can_seek; + iface->seek=plover_razor_input_stream_seek; + iface->can_truncate=plover_razor_input_stream_can_truncate; + iface->truncate_fn=plover_razor_input_stream_truncate; +} + +static void plover_razor_input_stream_pollable_iface_init( + GPollableInputStreamInterface *iface) +{ + iface->is_readable=plover_razor_input_stream_is_readable; + iface->create_source=plover_razor_input_stream_create_source; +} + +static void plover_razor_input_stream_init(PloverRazorInputStream *stream) +{ + stream->priv=G_TYPE_INSTANCE_GET_PRIVATE(stream, + PLOVER_TYPE_RAZOR_INPUT_STREAM,PloverRazorInputStreamPrivate); +} + +GInputStream *plover_razor_input_stream_new(const char *uri,GError **error) +{ + void *buf; + size_t len; + struct razor_error *tmp_error=NULL; + GInputStream *stream; + PloverRazorInputStreamPrivate *priv; + g_return_if_fail(uri!=NULL); + buf=razor_uri_get_contents(uri,&len,FALSE,&tmp_error); + if (!buf) + { + plover_propagate_razor_error(error,tmp_error); + return NULL; + } + stream=g_object_new(PLOVER_TYPE_RAZOR_INPUT_STREAM,NULL); + priv=PLOVER_RAZOR_INPUT_STREAM(stream)->priv; + priv->buf=buf; + priv->len=len; + return stream; +} + +static gssize plover_razor_input_stream_read(GInputStream *stream,void *buffer, + gsize count,GCancellable *cancellable,GError **error) +{ + PloverRazorInputStream *razor_stream; + PloverRazorInputStreamPrivate *priv; + razor_stream=PLOVER_RAZOR_INPUT_STREAM(stream); + priv=razor_stream->priv; + count=MIN(count,priv->len-priv->pos); + memcpy(buffer,(guint8 *)priv->buf+priv->pos,count); + priv->pos+=count; + return count; +} + +static gssize plover_razor_input_stream_skip(GInputStream *stream,gsize count, + GCancellable *cancellable,GError **error) +{ + PloverRazorInputStream *razor_stream; + PloverRazorInputStreamPrivate *priv; + razor_stream=PLOVER_RAZOR_INPUT_STREAM(stream); + priv=razor_stream->priv; + count=MIN(count,priv->len-priv->pos); + priv->pos+=count; + return count; +} + +static gboolean plover_razor_input_stream_close(GInputStream *stream, + GCancellable *cancellable,GError **error) +{ + return TRUE; +} + +static void plover_razor_input_stream_skip_async(GInputStream *stream, + gsize count,int io_priority,GCancellable *cancellable, + GAsyncReadyCallback callback,gpointer user_data) +{ + GTask *task; + gssize nskipped; + GError *error=NULL; + nskipped=G_INPUT_STREAM_GET_CLASS(stream)->skip(stream,count,cancellable, + &error); + task=g_task_new(stream,cancellable,callback,user_data); + if (error) + g_task_return_error(task,error); + else + g_task_return_int(task,nskipped); + g_object_unref(task); +} + +static gssize plover_razor_input_stream_skip_finish(GInputStream *stream, + GAsyncResult *result,GError **error) +{ + g_return_val_if_fail(g_task_is_valid(result,stream),-1); + return g_task_propagate_int(G_TASK(result),error); +} + +static void plover_razor_input_stream_close_async(GInputStream *stream, + int io_priority,GCancellable *cancellable,GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + task=g_task_new(stream,cancellable,callback,user_data); + g_task_return_boolean(task,TRUE); + g_object_unref (task); +} + +static gboolean plover_razor_input_stream_close_finish(GInputStream *stream, + GAsyncResult *result,GError **error) +{ + return TRUE; +} + +static goffset plover_razor_input_stream_tell(GSeekable *seekable) +{ + PloverRazorInputStream *razor_stream; + PloverRazorInputStreamPrivate *priv; + razor_stream=PLOVER_RAZOR_INPUT_STREAM(seekable); + priv=razor_stream->priv; + return priv->pos; +} + +static gboolean plover_razor_input_stream_can_seek(GSeekable *seekable) +{ + return TRUE; +} + +static gboolean plover_razor_input_stream_seek(GSeekable *seekable, + goffset offset,GSeekType type,GCancellable *cancellable,GError **error) +{ + PloverRazorInputStream *razor_stream; + PloverRazorInputStreamPrivate *priv; + goffset absolute; + razor_stream=PLOVER_RAZOR_INPUT_STREAM(seekable); + priv=razor_stream->priv; + switch(type) + { + case G_SEEK_CUR: + absolute=priv->pos+offset; + break; + case G_SEEK_SET: + absolute=offset; + break; + case G_SEEK_END: + absolute=priv->len+offset; + break; + default: + g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid GSeekType supplied")); + return FALSE; + } + if (absolute<0 || absolute>priv->len) + { + g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid seek request")); + return FALSE; + } + priv->pos=absolute; + return TRUE; +} + +static gboolean plover_razor_input_stream_can_truncate(GSeekable *seekable) +{ + return FALSE; +} + +static gboolean plover_razor_input_stream_truncate(GSeekable *seekable, + goffset offset,GCancellable *cancellable,GError **error) +{ + g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_NOT_SUPPORTED, + _("Cannot truncate PloverRazorInputStream")); + return FALSE; +} + +static gboolean + plover_razor_input_stream_is_readable(GPollableInputStream *stream) +{ + return TRUE; +} + +static GSource * + plover_razor_input_stream_create_source(GPollableInputStream *stream, + GCancellable *cancellable) +{ + GSource *base_source,*pollable_source; + base_source=g_timeout_source_new(0); + pollable_source=g_pollable_source_new_full(stream,base_source,cancellable); + g_source_unref(base_source); + return pollable_source; +} diff -r 772ff096a326 -r 31fb35727621 plover/inputstream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plover/inputstream.h Sat Jul 16 11:07:18 2016 +0100 @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2006-2007 Red Hat, Inc + * Copyright (C) 2016 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __PLOVER_INPUT_STREAM_H__ +#define __PLOVER_INPUT_STREAM_H__ + +#include + +G_BEGIN_DECLS + +#define PLOVER_TYPE_RAZOR_INPUT_STREAM plover_razor_input_stream_get_type() +#define PLOVER_RAZOR_INPUT_STREAM(o) G_TYPE_CHECK_INSTANCE_CAST(o, \ + PLOVER_TYPE_RAZOR_INPUT_STREAM, \ + PloverRazorInputStream) +#define PLOVER_RAZOR_INPUT_STREAM_CLASS(k) \ + G_TYPE_CHECK_CLASS_CAST(k, \ + PLOVER_TYPE_RAZOR_INPUT_STREAM, \ + PloverRazorInputStreamClass)) +#define PLOVER_IS_RAZOR_INPUT_STREAM(o) G_TYPE_CHECK_INSTANCE_TYPE(o, \ + PLOVER_TYPE_RAZOR_INPUT_STREAM) +#define PLOVER_IS_RAZOR_INPUT_STREAM_CLASS(k) \ + G_TYPE_CHECK_CLASS_TYPE(k, \ + PLOVER_TYPE_RAZOR_INPUT_STREAM) +#define PLOVER_RAZOR_INPUT_STREAM_GET_CLASS(o) \ + G_TYPE_INSTANCE_GET_CLASS(o, \ + PLOVER_TYPE_RAZOR_INPUT_STREAM, \ + PloverRazorInputStreamClass) + +/** + * PloverRazorInputStream: + * + * Implements #GInputStream for razor URI routines. + */ +typedef struct _PloverRazorInputStream PloverRazorInputStream; +typedef struct _PloverRazorInputStreamClass PloverRazorInputStreamClass; +typedef struct _PloverRazorInputStreamPrivate PloverRazorInputStreamPrivate; + +struct _PloverRazorInputStream +{ + GInputStream parent_instance; + PloverRazorInputStreamPrivate *priv; +}; + +struct _PloverRazorInputStreamClass +{ + GInputStreamClass parent_class; +}; + +GType plover_razor_input_stream_get_type(void) G_GNUC_CONST; +GInputStream *plover_razor_input_stream_new(const char *uri,GError **error); + +G_END_DECLS + +#endif /* _PLOVER_INPUT_STREAM_H__ */ diff -r 772ff096a326 -r 31fb35727621 plover/packageset.c --- a/plover/packageset.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/packageset.c Sat Jul 16 11:07:18 2016 +0100 @@ -32,7 +32,7 @@ G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT); typedef struct _PloverPackageSetPrivate { - gchar *install_root; + gchar *root_uri; struct razor_root *root; struct razor_set *set; GSList *packages; @@ -56,7 +56,7 @@ { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); g_free(priv->guessed_prefix); - g_free(priv->install_root); + g_free(priv->root_uri); G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj); } @@ -76,8 +76,8 @@ } if (priv->root) { - g_free(priv->install_root); - priv->install_root=NULL; + g_free(priv->root_uri); + priv->root_uri=NULL; razor_root_close(priv->root); priv->root=NULL; } @@ -120,25 +120,20 @@ } } -gboolean plover_package_set_open(PloverPackageSet *set,const char *install_root, +gboolean plover_package_set_open(PloverPackageSet *set,const char *root_uri, gboolean exclusive,GError **err) { struct razor_root *root=NULL; struct razor_set *system=NULL; PloverPackageSetPrivate *priv; struct razor_error *error=NULL; - GFile *file; - gchar *uri; g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE); - file=g_file_new_for_path(*install_root?install_root:"/"); - uri=g_file_get_uri(file); - g_object_unref(file); if (exclusive) { - root=razor_root_open(uri,NULL); + root=razor_root_open(root_uri,NULL); if (!root) { - if (razor_root_create(uri,&error)) + if (razor_root_create(root_uri,&error)) { if (razor_error_get_domain(error)==RAZOR_GENERAL_ERROR && razor_error_get_code(error)== @@ -146,15 +141,14 @@ { razor_error_free(error); error=NULL; - root=razor_root_open(uri,&error); + root=razor_root_open(root_uri,&error); } } else - root=razor_root_open(uri,&error); + root=razor_root_open(root_uri,&error); if (!root) { plover_propagate_razor_error(err,error); - g_free(uri); return FALSE; } } @@ -163,8 +157,7 @@ razor_set_ref(system); } else - system=razor_root_open_read_only(uri,&error); - g_free(uri); + system=razor_root_open_read_only(root_uri,&error); if (error) { g_set_error_literal(err,PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED, @@ -183,8 +176,8 @@ razor_root_close(priv->root); priv->root=NULL; } - g_free(priv->install_root); - priv->install_root=g_strdup(install_root); + g_free(priv->root_uri); + priv->root_uri=g_strdup(root_uri); priv->root=root; priv->set=system; return TRUE; @@ -195,7 +188,7 @@ PloverPackageSetPrivate *priv; g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); - return priv->install_root; + return priv->root_uri; } gboolean plover_package_set_get_exclusive(PloverPackageSet *set) @@ -634,7 +627,7 @@ struct razor_file_iterator *fi; GSList *packages,*lnk; PloverPackage *package; - default_prefix=plover_default_prefix_for_vendor(""); + default_prefix=plover_comps_get_default_prefix(NULL); if (!default_prefix) return; len=strlen(default_prefix); @@ -665,6 +658,7 @@ { GArray *popchart; const char *prefix; + struct comps *comps; PloverPackageSetPrivate *priv; g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); @@ -685,7 +679,56 @@ plover_package_set_popchart_free(popchart); } if (!priv->guessed_prefix) - priv->guessed_prefix= - plover_default_prefix_for_vendor("Acme Corporation"); + { + comps=plover_comps_new(); + plover_comps_set_vendor(comps,"Acme Corporation"); + priv->guessed_prefix=plover_comps_get_default_prefix(comps); + plover_comps_free(comps); + } return priv->guessed_prefix; } + +/* + * Returns: + * 0 if there are any files that don't match prefix, or + * -1 if there are no files at all, or + * 1 if there are files and they all match prefix. + */ + +int plover_package_set_files_match_prefix(PloverPackageSet *set, + const char *prefix) +{ + int len,matches=-1; + const char *name; + const char *install_root; + struct razor_package *package; + struct razor_package_iterator *pi; + struct razor_file_iterator *fi; + PloverPackageSetPrivate *priv; + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),-1); + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); + len=strlen(prefix); + while(len && prefix[len-1]=='/') + len--; + if (priv->set) + { + pi=razor_package_iterator_create(priv->set); + while (matches && + razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST)) + { + fi=razor_file_iterator_create(priv->set,package,0); + while (matches && razor_file_iterator_next(fi,&name)) + { + g_message("plover_package_set_files_match_prefix(%s): %s",prefix,name); + if (strncmp(name,prefix,len) || + name[len]!='\0' && name[len]!='/') + matches=0; + else + matches=1; + } + razor_file_iterator_destroy(fi); + } + razor_package_iterator_destroy(pi); + } + return matches; +} diff -r 772ff096a326 -r 31fb35727621 plover/packageset.h --- a/plover/packageset.h Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/packageset.h Sat Jul 16 11:07:18 2016 +0100 @@ -67,6 +67,8 @@ gboolean plover_package_set_get_no_details(PloverPackageSet *set); const char *plover_package_set_guess_prefix(PloverPackageSet *set, GError **error); +int plover_package_set_files_match_prefix(PloverPackageSet *set, + const char *prefix); G_END_DECLS diff -r 772ff096a326 -r 31fb35727621 plover/plover.h --- a/plover/plover.h Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/plover.h Sat Jul 16 11:07:18 2016 +0100 @@ -49,10 +49,18 @@ struct comps_requirement *packages; }; +enum comps_database_setting +{ + COMPS_DATABASE_GLOBAL = 0, /* Default value */ + COMPS_DATABASE_DISTRIBUTION_LOCAL, +}; + struct comps { char *vendor; struct comps_group *groups; + char *distribution; + enum comps_database_setting database; }; struct plover_vector @@ -61,10 +69,10 @@ char **strings; }; -gchar *plover_default_prefix_for_vendor(const char *vendor); gchar *plover_pre_install_prefix(void); void plover_purge_reports(const char *path); gchar *plover_get_reports_directory(void); +char *plover_get_program(const char *argv0); char *plover_get_program_directory(const char *argv0); GQuark plover_razor_error_quark(void); GQuark plover_posix_error_quark(void); @@ -92,11 +100,13 @@ int plover_installed_files_match_prefix(const char *prefix); struct comps *plover_comps_new(void); -struct comps *plover_comps_new_from_uri(const char *uri); +struct comps *plover_comps_new_from_uri(const char *uri,GError **error); struct comps *plover_comps_new_from_file(const char *filename); void plover_comps_free(struct comps *comps); struct comps_group *plover_comps_lookup_group(struct comps *comps, const char *id); +void plover_comps_set_vendor(struct comps *comps,const char *vendor); +gchar *plover_comps_get_default_prefix(struct comps *comps); int plover_log_open(const char *path); void plover_exception_handler_init(void); diff -r 772ff096a326 -r 31fb35727621 plover/razor.c --- a/plover/razor.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/razor.c Sat Jul 16 11:07:18 2016 +0100 @@ -18,6 +18,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#define _GNU_SOURCE #include #include #include @@ -48,7 +49,7 @@ * is met (in which case the action is consumed). */ int plover_run_transaction(struct razor_transaction *trans, - struct razor_install_iterator *ii,const char *install_root, + struct razor_install_iterator *ii,const char *root_uri, struct razor_set *system,PloverPackageSet *next,PloverRepository *upstream, struct razor_atomic *atomic,struct razor_relocations *relocations, enum razor_stage_type stage,GCancellable *cancellable) @@ -62,12 +63,9 @@ int r,count; GError *tmp_error=NULL; PloverPackage *package; - GFile *file; - gchar *uri; plover__uri_handler_init(); - file=g_file_new_for_path(*install_root?install_root:"/"); - uri=g_file_get_uri(file); - g_object_unref(file); + if (!*root_uri) + root_uri="file:/"; switch(stage) { case RAZOR_STAGE_SCRIPTS_PRE: @@ -89,7 +87,6 @@ { razor_atomic_abort(atomic,PLOVER_GENERAL_ERROR, PLOVER_GENERAL_ERROR_CANCELLED,"Operation was cancelled"); - g_free(uri); return -1; } if (action==RAZOR_INSTALL_ACTION_REMOVE) @@ -99,7 +96,7 @@ if (stage==RAZOR_STAGE_FILES) printf(" Removing : %s ",name); r=razor_package_remove(system,plover_package_set_get_razor(next), - atomic,pkg,uri,count,stage); + atomic,pkg,root_uri,count,stage); if (stage==RAZOR_STAGE_FILES) printf("\n"); } @@ -111,7 +108,6 @@ { plover_propagate_g_error(&error,tmp_error); razor_atomic_propagate_error(atomic,error,NULL); - g_free(uri); return -1; } if (stage==RAZOR_STAGE_FILES) @@ -119,22 +115,17 @@ if (relocations) razor_rpm_set_relocations(rpm,relocations); razor_transaction_fixup_package(trans,pkg,rpm); - r=razor_rpm_install(rpm,atomic,uri,1,stage); + r=razor_rpm_install(rpm,atomic,root_uri,1,stage); razor_rpm_close(rpm); if (stage==RAZOR_STAGE_FILES) printf("\n"); } - else if (action==RAZOR_INSTALL_ACTION_COMMIT) { - g_free(uri); + else if (action==RAZOR_INSTALL_ACTION_COMMIT) return 1; - } else r=0; if (razor_atomic_in_error_state(atomic)) - { - g_free(uri); return -1; - } else if (r) { if (action==RAZOR_INSTALL_ACTION_REMOVE) @@ -164,7 +155,6 @@ fprintf(stderr,"error: %s, exit status %d\n",t,r); razor_atomic_abort(atomic,PLOVER_SCRIPTLET_ERROR,r,t); g_free(t); - g_free(uri); return -1; } else @@ -174,7 +164,6 @@ name,version,arch,r); } } - g_free(uri); return 0; } @@ -209,23 +198,12 @@ GError **error) { gboolean retval; - GError *tmp_error=NULL; PloverTransaction *transaction; - transaction=plover_transaction_new_update_uri(base_uri,prefix,pkgs, - &tmp_error); + transaction=plover_transaction_new_update_uri(base_uri,prefix,pkgs,error); if (!transaction) - { - retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT); - if (retval) - g_error_free(tmp_error); - else - g_propagate_error(error,tmp_error); - } - else - { - retval=plover_transaction_commit(transaction,NULL,error); - g_object_unref(transaction); - } + return FALSE; + retval=plover_transaction_commit(transaction,NULL,error); + g_object_unref(transaction); return retval; } @@ -233,22 +211,12 @@ GError **error) { gboolean retval; - GError *tmp_error=NULL; PloverTransaction *transaction; - transaction=plover_transaction_new_update(base,prefix,pkgs,&tmp_error); + transaction=plover_transaction_new_update(base,prefix,pkgs,error); if (!transaction) - { - retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT); - if (retval) - g_error_free(tmp_error); - else - g_propagate_error(error,tmp_error); - } - else - { - retval=plover_transaction_commit(transaction,NULL,error); - g_object_unref(transaction); - } + return FALSE; + retval=plover_transaction_commit(transaction,NULL,error); + g_object_unref(transaction); return retval; } @@ -284,12 +252,15 @@ } /* - * Note: If there are no installed files, then any prefix will match. + * Returns: + * 0 if there are any installed files that don't match prefix, or + * -1 if there are no installed files at all, or + * 1 if there are installed files and they all match prefix. */ int plover_installed_files_match_prefix(const char *prefix) { - int len,matches=1; + int len,matches=-1; const char *name; const char *install_root; struct razor_set *set; @@ -316,6 +287,8 @@ if (strncmp(name,prefix,len) || name[len]!='\0' && name[len]!='/') matches=0; + else + matches=1; } razor_file_iterator_destroy(fi); } @@ -324,3 +297,204 @@ } return matches; } + +#include +#include + +struct razor_set_counter +{ + struct razor_set *set; + int count; +}; + +static GList *counters; + +static struct razor_set_counter *get_razor_set_counter(struct razor_set *set) +{ + GList *lnk; + struct razor_set_counter *counter; + for(lnk=counters;lnk;lnk=lnk->next) + { + counter=lnk->data; + if (counter->set==set) + return counter; + } + counter=g_new(struct razor_set_counter,1); + counter->set=set; + counter->count=0; + counters=g_list_prepend(counters,counter); + return counter; +} + +static void dump_razor_set_ref(struct razor_set *set) +{ + FILE *fp; + gchar *filename; + void *bt[16]; + size_t len; + struct razor_set_counter *counter; + filename=g_strdup_printf("razor-set-%p",set); + fp=fopen(filename,"a"); + g_free(filename); + counter=get_razor_set_counter(set); + counter->count++; + fprintf(fp,"Ref %p (%d refs)\n",set,counter->count); + fflush(fp); + len=backtrace(bt,G_N_ELEMENTS(bt)); + backtrace_symbols_fd(bt,len,fileno(fp)); + fprintf(fp,"\n"); + fclose(fp); +} + +static void dump_razor_set_unref(struct razor_set *set) +{ + FILE *fp; + gchar *filename; + void *bt[16]; + size_t len; + struct razor_set_counter *counter; + filename=g_strdup_printf("razor-set-%p",set); + fp=fopen(filename,"a"); + g_free(filename); + counter=get_razor_set_counter(set); + --counter->count; + fprintf(fp,"Unref %p (%d refs)\n",set,counter->count); + fflush(fp); + len=backtrace(bt,G_N_ELEMENTS(bt)); + backtrace_symbols_fd(bt,len,fileno(fp)); + fprintf(fp,"\n"); + fclose(fp); +} + +static void dump_razor_set_peek(struct razor_set *set) +{ + FILE *fp; + gchar *filename; + void *bt[16]; + size_t len; + struct razor_set_counter *counter; + filename=g_strdup_printf("razor-set-%p",set); + fp=fopen(filename,"a"); + g_free(filename); + counter=get_razor_set_counter(set); + fprintf(fp,"Peek %p (%d refs)\n",set,counter->count); + fflush(fp); + len=backtrace(bt,G_N_ELEMENTS(bt)); + backtrace_symbols_fd(bt,len,fileno(fp)); + fprintf(fp,"\n"); + fclose(fp); +} + +struct razor_set *razor_set_create_without_root(void) +{ + static struct razor_set *(*next)(void); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_set_create_without_root"); + set=(*next)(); + dump_razor_set_ref(set); + return set; +} + +struct razor_set *razor_set_create(void) +{ + static struct razor_set *(*next)(void); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_set_create"); + set=(*next)(); + dump_razor_set_ref(set); + return set; +} + +struct razor_set *razor_set_open(const char *uri,enum razor_set_flags flags, + struct razor_error **error) +{ + static struct razor_set *(*next)(const char *uri,enum razor_set_flags flags, + struct razor_error **error); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_set_open"); + set=(*next)(uri,flags,error); + dump_razor_set_ref(set); + return set; +} + +void razor_set_unref(struct razor_set *set) +{ + static void (*next)(struct razor_set *set); + if (!next) + next=dlsym(RTLD_NEXT,"razor_set_unref"); + if (!set) + abort(); + dump_razor_set_unref(set); + (*next)(set); +} + +struct razor_set *razor_set_ref(struct razor_set *set) +{ + static struct razor_set *(*next)(struct razor_set *set); + if (!next) + next=dlsym(RTLD_NEXT,"razor_set_ref"); + (*next)(set); + dump_razor_set_ref(set); + return set; +} + +struct razor_set * + razor_install_iterator_commit_set(struct razor_install_iterator *ii) +{ + static struct razor_set *(*next)(struct razor_install_iterator *ii); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_install_iterator_commit_set"); + set=(*next)(ii); + dump_razor_set_ref(set); + return set; +} + +struct razor_set *razor_transaction_commit(struct razor_transaction *trans) +{ + static struct razor_set *(*next)(struct razor_transaction *trans); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_transaction_commit"); + set=(*next)(trans); + dump_razor_set_ref(set); + return set; +} + +struct razor_set *razor_importer_finish(struct razor_importer *importer) +{ + static struct razor_set *(*next)(struct razor_importer *importer); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_importer_finish"); + set=(*next)(importer); + dump_razor_set_ref(set); + return set; +} + +struct razor_set *razor_root_open_read_only(const char *root_uri, + struct razor_error **error) +{ + static struct razor_set *(*next)(const char *root_uri, + struct razor_error **error); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_root_open_read_only"); + set=(*next)(root_uri,error); + dump_razor_set_ref(set); + return set; +} + +struct razor_set *razor_root_get_system_set(struct razor_root *root) +{ + static struct razor_set *(*next)(struct razor_root *root); + struct razor_set *set; + if (!next) + next=dlsym(RTLD_NEXT,"razor_root_get_system_set"); + set=(*next)(root); + dump_razor_set_peek(set); + return set; +} diff -r 772ff096a326 -r 31fb35727621 plover/transaction.c --- a/plover/transaction.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/transaction.c Sat Jul 16 11:07:18 2016 +0100 @@ -429,45 +429,31 @@ const char *install_root,GError **error) { PloverPackageSet *installed; - const char *install_uri; - gchar *install_path; + const char *root; + char *install_uri; GFile *file; gboolean retval; g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE); if (!install_root) { - install_uri=g_getenv("RAZOR_ROOT"); - if (install_uri) - { - file=g_file_new_for_uri(install_uri); - install_path=g_file_get_path(file); - g_object_unref(file); - if (!install_path) - { - g_set_error(error,PLOVER_GENERAL_ERROR, - PLOVER_GENERAL_ERROR_FAILED, - "%s: Not a local URI",install_uri); - return FALSE; - } - } - else - install_path=g_strdup("/"); + root=g_getenv("RAZOR_ROOT"); + install_uri=strdup(root?root:"file:/"); } else - install_path=g_strdup(install_root); - if (transaction->installed && !g_strcmp0(install_path, + install_uri=razor_path_to_uri(install_root); + if (transaction->installed && !g_strcmp0(install_uri, plover_package_set_get_install_root(transaction->installed))) { - g_free(install_path); + free(install_uri); return TRUE; } installed=plover_package_set_new(); - retval=plover_package_set_open(installed,install_path,TRUE,error); + retval=plover_package_set_open(installed,install_uri,TRUE,error); if (retval) plover_transaction_set_installed(transaction,installed); else g_object_unref(installed); - g_free(install_path); + free(install_uri); return retval; } @@ -514,13 +500,10 @@ const char *base,GError **error) { gboolean retval; - gchar *base_uri; - GFile *file; - file=g_file_new_for_path(base); - base_uri=g_file_get_uri(file); - g_object_unref(file); + char *base_uri; + base_uri=razor_path_to_uri(base); retval=plover_transaction_set_upstream_from_yum_uri(transaction,base_uri,error); - g_free(base_uri); + free(base_uri); return retval; } @@ -783,8 +766,8 @@ { int i,changed,is_leaf; uint32_t flags; - gchar *install_path; - const char *install_uri; + const char *root; + char *install_uri; const char *name,*version,*maybe_unused_name; struct razor_set *system,*upstream; struct razor_transaction *trans; @@ -800,29 +783,16 @@ struct razor_property_iterator *removed_props; if (!pkgs) return plover_transaction_new_remove(NULL,error); - install_uri=g_getenv("RAZOR_ROOT"); - if (install_uri) - { - file=g_file_new_for_uri(install_uri); - install_path=g_file_get_path(file); - g_object_unref(file); - if (!install_path) - { - g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED, - "%s: Not a local URI",install_uri); - return NULL; - } - } - else - install_path=g_strdup("/"); + root=g_getenv("RAZOR_ROOT"); + install_uri=strdup(root?root:"file:/"); installed=plover_package_set_new(); - if (!plover_package_set_open(installed,install_path,TRUE,error)) + if (!plover_package_set_open(installed,install_uri,TRUE,error)) { g_object_unref(installed); - g_free(install_path); + free(install_uri); return NULL; } - g_free(install_path); + free(install_uri); system=plover_package_set_get_razor(installed); package_names=plover_vector_new(); for(i=0;pkgs[i];i++) diff -r 772ff096a326 -r 31fb35727621 plover/util.c --- a/plover/util.c Fri Jul 08 08:33:44 2016 +0100 +++ b/plover/util.c Sat Jul 16 11:07:18 2016 +0100 @@ -29,8 +29,9 @@ #include "config.h" #include "plover.h" -gchar *plover_default_prefix_for_vendor(const char *vendor) +gchar *plover_comps_get_default_prefix(struct comps *comps) { + const char *vendor_prefix; #ifdef WIN32 /* * We want to sidestep any redirecting that MS-Windows may @@ -55,15 +56,17 @@ buf); program_files=buf; } - return g_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL); + vendor_prefix=program_files; #else - const char *vendor_prefix; vendor_prefix=g_getenv("PLOVER_VENDOR_PREFIX"); +#endif if (!vendor_prefix) return NULL; + else if (!comps) + return g_build_filename(vendor_prefix,"Plover",NULL); else - return g_build_filename(vendor_prefix,vendor?vendor:"Plover",NULL); -#endif + return g_build_filename(vendor_prefix, + comps->vendor?comps->vendor:"Plover",comps->distribution,NULL); } gchar *plover_pre_install_prefix(void) diff -r 772ff096a326 -r 31fb35727621 setup/setup.c --- a/setup/setup.c Fri Jul 08 08:33:44 2016 +0100 +++ b/setup/setup.c Sat Jul 16 11:07:18 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011 J. Ali Harlow + * Copyright (C) 2009, 2011, 2016 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 @@ -33,25 +33,89 @@ void setup(const char *argv0) { - char *path; - gchar *s,*prefix; + char *yum_uri,*local_database,*active_database,*alternate_database; + gchar *s,*prefix,*distribution,*vendor_prefix; int ch,changed; struct comps *comps; struct comps_group *group; struct comps_requirement *pkg; struct plover_vector *packages=NULL; GError *error=NULL; - path=plover_get_program_directory(argv0); - s=g_strconcat(path,"/repodata/comps.xml",NULL); - comps=plover_comps_new_from_file(s); + s=plover_get_program(argv0); + yum_uri=razor_path_to_uri(s); + g_free(s); + s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL); + comps=plover_comps_new_from_uri(s,&error); + g_free(s); + if (g_error_matches(error,PLOVER_RAZOR_ERROR, + RAZOR_GENERAL_ERROR_UNSUPPORTED_ARCHIVE)) + { + g_clear_error(&error); + free(yum_uri); + s=plover_get_program_directory(argv0); + yum_uri=razor_path_to_uri(s); + g_free(s); + s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL); + comps=plover_comps_new_from_uri(s,&error); + } if (!comps) { - perror(s); + fprintf(stderr,"%s\n",error->message); + g_error_free(error); exit(1); } - g_free(s); - prefix=plover_default_prefix_for_vendor(comps->vendor); - if (!plover_installed_files_match_prefix(prefix)) + prefix=plover_comps_get_default_prefix(comps); + if (prefix) + { + s=g_strconcat(prefix,"/var/lib/razor",NULL); + local_database=razor_path_to_uri(s); + g_free(s); + } + else + local_database=NULL; + switch(comps->database) + { + case COMPS_DATABASE_DISTRIBUTION_LOCAL: + active_database=local_database; + alternate_database=NULL; + break; + case COMPS_DATABASE_GLOBAL: + active_database=NULL; + alternate_database=local_database; + break; + } + if (prefix) + { + distribution=g_strdup(comps->distribution); + plover_comps_set_distribution(comps,NULL); + vendor_prefix=plover_comps_get_default_prefix(comps); + plover_comps_set_distribution(comps,distribution); + g_free(distribution); + razor_set_database_uri(alternate_database); + if (plover_installed_files_match_prefix(vendor_prefix)==1) + { + printf("There is an existing installation under %s\n" + "which is not compatible with this distribution. In order\n" + "to continue, the existing installation must be uninstalled.\n" + "Do you want to remove all packages in the existing installion? ", + prefix); + ch=getchar(); + if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n') + exit(1); + while(ch!='\n' && ch!=EOF) + ch=getchar(); + if (plover_remove(NULL,&error)) + { + fprintf(stderr,"%s\n",error->message); + g_error_free(error); + exit(1); + } + } + g_free(vendor_prefix); + } + razor_set_database_uri(active_database); + free(local_database); + if (prefix && !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" @@ -98,7 +162,7 @@ fprintf(stderr,"No packages to install\n"); exit(1); } - if (!plover_install(path,prefix,packages->strings,&error)) + if (!plover_install_uri(yum_uri,prefix,packages->strings,&error)) { fprintf(stderr,"%s\n",error->message); g_error_free(error); @@ -106,7 +170,7 @@ } plover_vector_free(packages); g_free(prefix); - free(path); + free(yum_uri); } int main(int argc,char **argv) diff -r 772ff096a326 -r 31fb35727621 tests/Makefile.am --- a/tests/Makefile.am Fri Jul 08 08:33:44 2016 +0100 +++ b/tests/Makefile.am Sat Jul 16 11:07:18 2016 +0100 @@ -2,7 +2,7 @@ EXTRA_DIST = zsh.spec zsh2.spec zip.spec zap.spec filesystem.spec zappy.spec \ zappy2.spec unsatisfiable.spec uninstallable.spec badpostun.spec comps.xml \ - glib.supp.in README xvfb-run + distribution-local-comps.xml glib.supp.in README xvfb-run pkg_V_rpmbuild = $(pkg_v_rpmbuild_$(V)) pkg_v_rpmbuild_ = $(pkg_v_rpmbuild_$(AM_DEFAULT_VERBOSITY)) @@ -13,7 +13,8 @@ if HAVE_CHECK_TOOLS noinst_DATA = glib.supp yum-repo-test-dir/repodata/primary.xml.gz \ - primary.xml.gz razor-test-dir/var/lib/razor/system.rzdb + distribution-local-test-dir/repodata/primary.xml.gz \ + razor-test-dir/var/lib/razor/system.rzdb if HAVE_VALGRIND_3_9 %.supp: %.supp.in @@ -23,6 +24,22 @@ grep -v '^ *match-leak-kinds: ' $< > $@ endif +distribution-local-test-dir/repodata/primary.xml.gz: filesystem.spec \ + zappy.spec Makefile + rm -rf rpmbuild distribution-local-test-dir + mkdir -p rpmbuild/BUILD rpmbuild/RPMS + $(BUILD_RPM) $(srcdir)/filesystem.spec + $(BUILD_RPM) $(srcdir)/zappy.spec + mkdir -p distribution-local-test-dir/Packages + mv rpmbuild/RPMS/noarch/*.rpm distribution-local-test-dir/Packages + rm -rf rpmbuild + cp $(srcdir)/distribution-local-comps.xml \ + distribution-local-test-dir/comps.xml + $(CREATEREPO) --simple-md-filenames -g comps.xml \ + distribution-local-test-dir + mv distribution-local-test-dir/comps.xml \ + distribution-local-test-dir/repodata + yum-repo-test-dir/repodata/primary.xml.gz: zsh.spec zsh2.spec zip.spec \ zap.spec filesystem.spec zappy.spec zappy2.spec unsatisfiable.spec \ uninstallable.spec badpostun.spec Makefile @@ -45,13 +62,7 @@ $(CREATEREPO) --simple-md-filenames -g comps.xml yum-repo-test-dir mv yum-repo-test-dir/comps.xml yum-repo-test-dir/repodata -primary.xml.gz: yum-repo-test-dir/repodata/primary.xml.gz - cp yum-repo-test-dir/repodata/primary.xml.gz \ - yum-repo-test-dir/repodata/filelists.xml.gz . - rm -rf rpms - ln -s yum-repo-test-dir/rpms . - -razor-test-dir/var/lib/razor/system.rzdb: primary.xml.gz +razor-test-dir/var/lib/razor/system.rzdb: yum-repo-test-dir/repodata/primary.xml.gz $(RM) -r razor-test-dir $(RAZOR) --root=file:razor-test-dir init $(RAZOR) --url=file://localhost`pwd`/yum-repo-test-dir \ @@ -71,7 +82,7 @@ done clean-local: - rm -rf yum-repo-test-dir razor-test-dir - rm -f primary.xml.gz filelists.xml.gz rpms rawhide.rzdb + rm -rf yum-repo-test-dir distribution-local-test-dir razor-test-dir + rm -f rawhide.rzdb CLEANFILES = glib.supp diff -r 772ff096a326 -r 31fb35727621 tests/plover-gtk/test-transactionhelper.c --- a/tests/plover-gtk/test-transactionhelper.c Fri Jul 08 08:33:44 2016 +0100 +++ b/tests/plover-gtk/test-transactionhelper.c Sat Jul 16 11:07:18 2016 +0100 @@ -29,6 +29,16 @@ GtkBuilder *ui; gboolean manual_mode=FALSE; +#if 0 +static void complete_changed(GtkWidget *page,GParamSpec *child_property, + PloverTransactionHelper *helper) +{ + g_message("complete child property for %s now %s", + gtk_buildable_get_name(GTK_BUILDABLE(page)), + gtk_assistant_get_page_complete(helper->assistant,page)?"TRUE":"FALSE"); +} +#endif + PloverTransactionHelper *get_transaction_helper(void) { const char *dir; @@ -43,6 +53,23 @@ g_free(s); helper=plover_transaction_helper_new(ui); g_object_unref(ui); +#if 0 + if (helper->assistant) + { + GtkWidget *page; + int i; + for(i=gtk_assistant_get_n_pages(helper->assistant)-1;i>=0;i--) + { + page=gtk_assistant_get_nth_page(helper->assistant,i); + g_signal_connect(page,"child-notify::complete", + G_CALLBACK(complete_changed),helper); + g_message("complete child property for %s initially %s", + gtk_buildable_get_name(GTK_BUILDABLE(page)), + gtk_assistant_get_page_complete(helper->assistant,page)? + "TRUE":"FALSE"); + } + } +#endif return helper; } @@ -56,6 +83,8 @@ static void test_basic_properties(void) { const char *prefix; + char *uri; + gchar *default_prefix; GError *err=NULL; struct comps *comps; PloverTransactionHelper *helper; @@ -64,7 +93,9 @@ upstream=plover_repository_new_from_yum("../yum-repo-test-dir",&err); if (!upstream) g_error("../yum-repo-test-dir: %s",err->message); - installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + uri=razor_path_to_uri("../razor-test-dir"); + installed=plover_package_set_new_from_installed(uri,&err); + free(uri); if (!installed) g_error("../razor-test-dir: %s",err->message); helper=get_transaction_helper(); @@ -81,7 +112,12 @@ g_assert(plover_comps_lookup_group(comps,"base")); prefix=plover_transaction_helper_get_prefix(helper,&err); g_assert(!err); - g_assert_cmpstr(prefix,==,plover_default_prefix_for_vendor("Acme Corporation")); + comps=plover_comps_new(); + plover_comps_set_vendor(comps,"Acme Corporation"); + default_prefix=plover_comps_get_default_prefix(comps); + plover_comps_free(comps); + g_assert_cmpstr(prefix,==,default_prefix); + g_free(default_prefix); g_assert(!plover_transaction_helper_get_visible(helper)); g_assert(!plover_transaction_helper_get_error(helper,NULL)); g_object_unref(upstream); @@ -91,21 +127,21 @@ static void test_install_group(void) { - gchar *root,*root_uri; + gchar *root; GError *err=NULL; - GFile *file; + char *uri; PloverPackageSet *installed; PloverTransactionHelper *helper; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); + uri=razor_path_to_uri(root); g_free(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + g_setenv("RAZOR_ROOT",uri,TRUE); + free(uri); helper=get_transaction_helper(); - installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + uri=razor_path_to_uri("../razor-test-dir"); + installed=plover_package_set_new_from_installed(uri,&err); + free(uri); if (!installed) g_error("../razor-test-dir: %s",err->message); plover_transaction_helper_set_installed(helper,installed); @@ -120,20 +156,17 @@ static void test_remove_group(void) { - gchar *root,*root_uri; + gchar *root; + char *uri; GError *err=NULL; - GFile *file; PloverPackageSet *installed; PloverTransactionHelper *helper; struct plover_vector *packages; char *pkgs[]={"zip",NULL}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); packages=plover_transaction_helper_group_get_default_packages(helper, @@ -143,7 +176,7 @@ if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err)) g_error("plover_install: %s",err->message); plover_vector_free(packages); - installed=plover_package_set_new_from_installed(root,&err); + installed=plover_package_set_new_from_installed(uri,&err); if (!installed) g_error("%s: %s",root,err->message); plover_transaction_helper_set_installed(helper,installed); @@ -153,26 +186,26 @@ g_assert(!err); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); + free(uri); g_free(root); } static void test_update(void) { - gchar *root,*root_uri; + gchar *root; + char *uri; GError *err=NULL; - GFile *file; PloverPackageSet *installed; PloverTransactionHelper *helper; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); - g_free(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); + g_free(uri); helper=get_transaction_helper(); - installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + uri=razor_path_to_uri("../razor-test-dir"); + installed=plover_package_set_new_from_installed(uri,&err); + free(uri); if (!installed) g_error("../razor-test-dir: %s",err->message); plover_transaction_helper_set_installed(helper,installed); @@ -204,6 +237,19 @@ struct run_install_baton *baton=data; GtkWidget *page; GtkAssistant *assistant=baton->helper->assistant; +#if 0 + page=gtk_assistant_get_nth_page(assistant, + gtk_assistant_get_current_page(assistant)); + g_message("run_install_tick: state is %s, on page %s", + baton->state==RI_STATE_INIT?"INIT": + baton->state==RI_STATE_SUMMARY?"SUMMARY": + baton->state==RI_STATE_PROGRESS?"PROGRESS": + baton->state==RI_STATE_PROGRESS_DELAY?"PROGRESS_DELAY": + baton->state==RI_STATE_DONE?"DONE": + baton->state==RI_STATE_FINISH?"FINISH": + "Unknown", + gtk_buildable_get_name(GTK_BUILDABLE(page))); +#endif switch(baton->state) { case RI_STATE_INIT: @@ -215,6 +261,7 @@ case RI_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; + g_assert(gtk_widget_is_sensitive(assistant->apply)); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; @@ -254,23 +301,20 @@ static void test_run_install(void) { - gchar *root,*root_uri; + gchar *root; + char *uri; GError *err=NULL; - GFile *file; struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; struct run_install_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); helper=get_transaction_helper(); installed=plover_package_set_new(); - if (!plover_package_set_open(installed,root,TRUE,&err)) + if (!plover_package_set_open(installed,uri,TRUE,&err)) g_error("%s: %s",root,err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); @@ -287,6 +331,7 @@ gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); + free(uri); g_free(root); } @@ -320,6 +365,7 @@ case RR_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; + g_assert(gtk_widget_is_sensitive(assistant->apply)); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; @@ -359,20 +405,17 @@ static void test_run_remove(void) { - gchar *root,*root_uri; + gchar *root; + char *uri; GError *err=NULL; - GFile *file; struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; struct run_remove_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); packages= @@ -383,7 +426,7 @@ g_error("plover_install: %s",err->message); plover_vector_free(packages); installed=plover_package_set_new(); - if (!plover_package_set_open(installed,root,TRUE,&err)) + if (!plover_package_set_open(installed,uri,TRUE,&err)) g_error("%s: %s",root,err->message); plover_transaction_helper_set_installed(helper,installed); g_object_unref(installed); @@ -396,6 +439,7 @@ gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); + free(uri); g_free(root); } @@ -429,6 +473,7 @@ case RU_STATE_SUMMARY: if (gtk_assistant_get_current_page(assistant)<1) return TRUE; + g_assert(gtk_widget_is_sensitive(assistant->apply)); if (!manual_mode) gtk_button_clicked(GTK_BUTTON(assistant->apply)); break; @@ -468,9 +513,9 @@ static void test_run_update(void) { - gchar *root,*root_uri; + gchar *root; + char *uri; GError *err=NULL; - GFile *file; struct razor_importer *importer; struct razor_set *downgraded; struct razor_atomic *atomic; @@ -480,15 +525,12 @@ struct run_update_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); installed=plover_package_set_new(); - if (!plover_package_set_open(installed,root,TRUE,&err)) + if (!plover_package_set_open(installed,uri,TRUE,&err)) g_error("%s: %s",root,err->message); importer=razor_importer_create(); razor_importer_begin_package(importer,"zappy","0-1","noarch"); @@ -513,6 +555,7 @@ gtk_main(); g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); + free(uri); g_free(root); } @@ -590,8 +633,8 @@ static void test_check_vendor(void) { int fh; - gchar *root,*root_uri,*s; - GFile *file; + gchar *root,*s; + char *uri; GError *err=NULL; struct razor_importer *importer; struct razor_set *downgraded; @@ -599,19 +642,17 @@ struct plover_vector *packages; PloverPackageSet *installed; PloverTransactionHelper *helper; - struct run_update_baton baton={0,}; + struct check_vendor_baton baton={0,}; g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE); root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); helper=get_transaction_helper(); plover_transaction_helper_set_check_vendor(helper,TRUE); plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); installed=plover_package_set_new(); - if (!plover_package_set_open(installed,root,TRUE,&err)) + if (!plover_package_set_open(installed,uri,TRUE,&err)) g_error("%s: %s",root,err->message); importer=razor_importer_create(); razor_importer_begin_package(importer,"zappy","0-1","noarch"); @@ -622,8 +663,8 @@ razor_importer_finish_package(importer); downgraded=razor_importer_finish(importer); atomic=razor_atomic_open("Add downgraded packages"); - razor_atomic_make_dirs(atomic,root_uri,"/test/bin/zappy"); - s=g_build_filename(root_uri,"test/bin/zappy",NULL); + razor_atomic_make_dirs(atomic,uri,"/test/bin/zappy"); + s=g_build_filename(uri,"test/bin/zappy",NULL); fh=razor_atomic_create_file(atomic,s,S_IRWXU|S_IRWXG|S_IRWXO); g_free(s); razor_atomic_close(atomic,fh); @@ -644,10 +685,139 @@ g_object_unref(helper); g_unsetenv("RAZOR_ROOT"); g_free(root); - g_free(root_uri); + free(uri); g_unsetenv("PLOVER_VENDOR_PREFIX"); } +static gchar *create_new_root_and_install(gchar **prefix_p,char **pkgs) +{ + gchar *root,*prefix; + char *uri; + GError *err=NULL; + struct comps *comps; + PloverTransaction *transaction; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + uri=razor_path_to_uri(root); + g_setenv("RAZOR_ROOT",uri,TRUE); + free(uri); + uri=razor_path_to_uri("../yum-repo-test-dir/repodata/comps.xml"); + comps=plover_comps_new_from_uri(uri,&err); + free(uri); + if (!comps) + g_error("../yum-repo-test-dir/repodata/comps.xml: %s",err->message); + prefix=plover_comps_get_default_prefix(comps); + plover_comps_free(comps); + transaction=plover_transaction_new_install("../yum-repo-test-dir",prefix, + pkgs,&err); + if (!transaction) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(plover_transaction_commit(transaction,NULL,NULL)); + g_object_unref(transaction); + fflush(stdout); + if (prefix_p) + *prefix_p=prefix; + else + g_free(prefix); + return root; +} + +static check_file(const char *root,const char *path) +{ + gchar *s; + s=g_build_filename(root,path,NULL); + g_assert(g_file_test(s,G_FILE_TEST_EXISTS)); + g_free(s); +} + +static check_no_file(const char *root,const char *path) +{ + gchar *s; + s=g_build_filename(root,path,NULL); + g_assert(!g_file_test(s,G_FILE_TEST_EXISTS)); + g_free(s); +} + +/* + * Test that installing from a repository which is marked as distribution-local + * on top of an existing global installation works if prefix is NULL + * (which is the case on UNIX if PLOVER_VENDOR_PREFIX is not set). + */ +static void test_unprefixed_distribution_local(void) +{ + gchar *root; + GError *err=NULL; + char *pkgs[]={"zap",NULL}; + struct plover_vector *packages; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct run_install_baton baton={0,}; + g_unsetenv("PLOVER_VENDOR_PREFIX"); + root=create_new_root_and_install(NULL,pkgs); + check_file(root,"/usr/bin/zap"); + helper=get_transaction_helper(); + plover_transaction_helper_set_check_vendor(helper,TRUE); + plover_transaction_helper_set_base(helper,"../distribution-local-test-dir"); + packages=plover_vector_new(); + plover_vector_append(packages,"zappy"); + if (!plover_transaction_helper_install_packages(helper,packages,&err)) + g_error("zappy: %s",err->message); + g_assert(!err); + plover_vector_free(packages); + plover_transaction_helper_present(helper); + baton.helper=helper; + baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,&baton,NULL); + gtk_main(); + g_object_unref(helper); + check_file(root,"/usr/bin/zappy"); + g_free(root); + g_unsetenv("RAZOR_ROOT"); +} + +/* + * Test that installing from a repository which is marked as distribution-local + * on top of an existing global installation requires removing the existing + * installation if prefix is non-NULL (which is the case if PLOVER_VENDOR_PREFIX + * is set). + */ +static void test_prefixed_distribution_local(void) +{ + gchar *root,*s; + gchar *prefix; + GError *err=NULL; + char *pkgs[]={"zap",NULL}; + struct plover_vector *packages; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct check_vendor_baton baton={0,}; + g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE); + helper=get_transaction_helper(); + plover_transaction_helper_set_check_vendor(helper,TRUE); + plover_transaction_helper_set_base(helper,"../distribution-local-test-dir"); + root=create_new_root_and_install(&prefix,pkgs); + s=g_build_filename(prefix,"bin/zap",NULL); + check_file(root,s); + g_free(s); + packages=plover_vector_new(); + plover_vector_append(packages,"filesystem"); + if (!plover_transaction_helper_install_packages(helper,packages,&err)) + g_error("filesystem: %s",err->message); + g_assert(!err); + plover_vector_free(packages); + plover_transaction_helper_present(helper); + baton.helper=helper; + baton.eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,&baton,NULL); + gtk_main(); + g_object_unref(helper); + s=g_build_filename(prefix,"bin/zap",NULL); + check_no_file(root,s); + g_free(s); + check_no_file(root,"/media"); + g_free(root); + g_free(prefix); + g_unsetenv("RAZOR_ROOT"); +} + struct set_error_baton { enum { SE_STATE_INIT = 0, @@ -687,24 +857,24 @@ static void test_set_error(void) { - gchar *root,*root_uri; + gchar *root; + char *uri; const char *errmsg; GError *err=NULL; const GError *err2=NULL; - GFile *file; PloverPackageSet *installed; PloverTransactionHelper *helper; struct set_error_baton baton={0,}; root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - file=g_file_new_for_path(root); + uri=razor_path_to_uri(root); g_free(root); - root_uri=g_file_get_uri(file); - g_object_unref(file); - g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + g_setenv("RAZOR_ROOT",uri,TRUE); + free(uri); helper=get_transaction_helper(); - installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + uri=razor_path_to_uri("../razor-test-dir"); + installed=plover_package_set_new_from_installed(uri,&err); + free(uri); if (!installed) g_error("../razor-test-dir: %s",err->message); plover_transaction_helper_set_installed(helper,installed); @@ -759,6 +929,10 @@ g_test_add_func("/transactionhelper/run-remove",test_run_remove); g_test_add_func("/transactionhelper/run-update",test_run_update); g_test_add_func("/transactionhelper/check-vendor",test_check_vendor); + g_test_add_func("/transactionhelper/unprefixed-distribution-local", + test_unprefixed_distribution_local); + g_test_add_func("/transactionhelper/prefixed-distribution-local", + test_prefixed_distribution_local); g_test_add_func("/transactionhelper/set-error",test_set_error); retval=g_test_run(); return retval; diff -r 772ff096a326 -r 31fb35727621 tests/plover/test-packageset.c --- a/tests/plover/test-packageset.c Fri Jul 08 08:33:44 2016 +0100 +++ b/tests/plover/test-packageset.c Sat Jul 16 11:07:18 2016 +0100 @@ -55,6 +55,7 @@ struct razor_set *set; struct razor_package *pkg; struct razor_package_iterator *iter; + struct comps *comps; PloverPackage *package; GError *err=NULL; const char *prefix; @@ -79,7 +80,10 @@ if (!prefix && err) g_error("plover_package_set_guess_prefix: %s",err->message); g_assert(err == NULL); - default_prefix=plover_default_prefix_for_vendor("Acme Corporation"); + comps=plover_comps_new(); + plover_comps_set_vendor(comps,"Acme Corporation"); + default_prefix=plover_comps_get_default_prefix(comps); + plover_comps_free(comps); g_assert_cmpstr(prefix,==,default_prefix); g_free(default_prefix); } @@ -164,23 +168,29 @@ static void verify_zappy_set(PloverPackageSet *package_set) { + char *root_uri; verify_package_set(package_set,G_N_ELEMENTS(zappy_packages),zappy_packages, NULL); + root_uri=razor_path_to_uri("../razor-test-dir"); g_assert_cmpstr(plover_package_set_get_install_root(package_set),==, - "../razor-test-dir"); + root_uri); + free(root_uri); } static void test_open(void) { + char *root_uri; PloverPackageSet *package_set; GError *err=NULL; package_set=plover_package_set_new(); g_assert(PLOVER_IS_PACKAGE_SET(package_set)); - if (!plover_package_set_open(package_set,"../razor-test-dir",FALSE,&err)) + root_uri=razor_path_to_uri("../razor-test-dir"); + if (!plover_package_set_open(package_set,root_uri,FALSE,&err)) { g_assert(err && err->message); g_error("../razor-test-dir: %s",err->message); } + free(root_uri); g_assert(!err); verify_zappy_set(package_set); plover_package_set_close(package_set); @@ -195,17 +205,20 @@ struct razor_package *pkg; struct razor_package_iterator *iter; struct razor_atomic *atomic; + struct comps *comps; PloverPackageSet *package_set; PloverPackage *package; GError *err=NULL; const char *prefix; - gchar *root; + char root[]="razor-test-dir-XXXXXX"; + char *root_uri; + gchar *default_prefix; GSList *packages; package_set=plover_package_set_new(); g_assert(PLOVER_IS_PACKAGE_SET(package_set)); - root=g_strdup("razor-test-dir-XXXXXX"); g_assert(mkdtemp(root)); - if (!plover_package_set_open(package_set,root,TRUE,&err)) + root_uri=razor_path_to_uri(root); + if (!plover_package_set_open(package_set,root_uri,TRUE,&err)) { g_assert(err && err->message); g_error("%s: %s",root,err->message); @@ -216,8 +229,9 @@ g_assert(plover_package_set_set_header_version(package_set, RAZOR_HEADER_VERSION_MIN)); g_assert(plover_package_set_set_header_version(package_set,ver)); - g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,root); - g_free(root); + g_assert_cmpstr(plover_package_set_get_install_root(package_set),==, + root_uri); + free(root_uri); g_assert(plover_package_set_get_exclusive(package_set)); set=plover_package_set_get_razor(package_set); g_assert(set != NULL); @@ -246,8 +260,12 @@ if (!prefix && err) g_error("plover_package_set_guess_prefix: %s",err->message); g_assert(err == NULL); - g_assert_cmpstr(prefix,==, - plover_default_prefix_for_vendor("Acme Corporation")); + comps=plover_comps_new(); + plover_comps_set_vendor(comps,"Acme Corporation"); + default_prefix=plover_comps_get_default_prefix(comps); + plover_comps_free(comps); + g_assert_cmpstr(prefix,==,default_prefix); + g_free(default_prefix); plover_package_set_close(package_set); g_object_unref(package_set); } @@ -257,7 +275,10 @@ PloverPackageSet *package_set; PloverPackage *package; GError *err=NULL; - package_set=plover_package_set_new_from_installed("../razor-test-dir",&err); + char *root_uri; + root_uri=razor_path_to_uri("../razor-test-dir"); + package_set=plover_package_set_new_from_installed(root_uri,&err); + free(root_uri); if (!package_set && err) g_error("../razor-test-dir: %s",err->message); g_assert(PLOVER_IS_PACKAGE_SET(package_set)); diff -r 772ff096a326 -r 31fb35727621 tests/plover/test-transaction.c --- a/tests/plover/test-transaction.c Fri Jul 08 08:33:44 2016 +0100 +++ b/tests/plover/test-transaction.c Sat Jul 16 11:07:18 2016 +0100 @@ -56,14 +56,11 @@ struct razor_package *pkg; enum razor_install_action action; int count; - gchar *root_uri; + char *root_uri; GError *err=NULL; - GFile *file; - file=g_file_new_for_path("../razor-test-dir"); - root_uri=g_file_get_uri(file); - g_object_unref(file); + root_uri=razor_path_to_uri("../razor-test-dir"); g_setenv("RAZOR_ROOT",root_uri,TRUE); - g_free(root_uri); + free(root_uri); transaction=plover_transaction_new_update("../yum-repo-test-dir","/test", NULL,&err); if (!transaction && err) @@ -215,7 +212,6 @@ g_assert_cmpstr(name,==,"uninstallable"); g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count)); g_assert(!plover_transaction_commit(transaction,NULL,&err)); - g_message("plover_transaction_commit: %s",err->message); g_assert_cmpint(err->domain,==,PLOVER_RAZOR_ERROR); g_assert_cmpint(err->code,==,RAZOR_GENERAL_ERROR_FAILED); g_clear_error(&err); diff -r 772ff096a326 -r 31fb35727621 tests/plover/test-uri-handler.c --- a/tests/plover/test-uri-handler.c Fri Jul 08 08:33:44 2016 +0100 +++ b/tests/plover/test-uri-handler.c Sat Jul 16 11:07:18 2016 +0100 @@ -47,13 +47,13 @@ g_setenv("RAZOR_ROOT",root_uri,TRUE); g_free(root_uri); comps=plover_comps_new_from_uri( - "resource:///uk/co/juiblex/project/plover/repodata/comps.xml"); + "resource:///uk/co/juiblex/project/plover/repodata/comps.xml",&error); if (!comps) { - perror("resource:///uk/co/juiblex/project/plover/repodata/comps.xml"); + fprintf(stderr,"%s\n",error->message); exit(1); } - prefix=plover_default_prefix_for_vendor(comps->vendor); + prefix=plover_comps_get_default_prefix(comps); group=plover_comps_lookup_group(comps,"base"); if (!group) { diff -r 772ff096a326 -r 31fb35727621 update/Makefile.am --- a/update/Makefile.am Fri Jul 08 08:33:44 2016 +0100 +++ b/update/Makefile.am Sat Jul 16 11:07:18 2016 +0100 @@ -3,28 +3,20 @@ INCLUDES=-I$(top_srcdir) CCLD = $(CXX) -bin_PROGRAMS=update updatez +bin_PROGRAMS=update bin_SCRIPTS=update.js update_SOURCES=update.c update_LDFLAGS=-all-static update_LIBTOOLFLAGS=--tag=CXX if HAVE_WINDRES -update_SOURCES+=update-res.rc update.exe.manifest -endif - -updatez_SOURCES=updatez.c -updatez_LDFLAGS=-all-static -updatez_LIBTOOLFLAGS=--tag=CXX -if HAVE_WINDRES -updatez_SOURCES+=updatez-res.rc updatez.exe.manifest +update_SOURCES+=resources.rc update.exe.manifest endif .rc.$(OBJEXT): $(AM_V_GEN)$(WINDRES) $< $@ -update-res.$(OBJEXT): update-res.rc update.exe.manifest update.ico -updatez-res.$(OBJEXT): updatez-res.rc updatez.exe.manifest update.ico +resources.$(OBJEXT): resources.rc update.exe.manifest update.ico %.js: $(srcdir)/%.js.in $(AM_V_GEN)sed -e 's/$$/\r/' $(srcdir)/$@.in > $@ diff -r 772ff096a326 -r 31fb35727621 update/manifest.xml.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/update/manifest.xml.in Sat Jul 16 11:07:18 2016 +0100 @@ -0,0 +1,22 @@ +changequote([,])dnl + + + + Plover update program + + + + + + + + + + + + + + diff -r 772ff096a326 -r 31fb35727621 update/resources.rc.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/update/resources.rc.in Sat Jul 16 11:07:18 2016 +0100 @@ -0,0 +1,37 @@ +#include +#include + +#pragma code_page(65001) + +MAINICON ICON "update.ico" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@, + @PLOVER_MICRO_VERSION@,0 + PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@, + @PLOVER_MICRO_VERSION@,0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + { + BLOCK "StringFileInfo" + { + BLOCK "080904B0" + { + VALUE "CompanyName","The plover development team" + VALUE "FileDescription","Plover update program" + VALUE "FileVersion","@PACKAGE_VERSION@" + VALUE "InternalName","update" + VALUE "LegalCopyright", + "Copyright © 2009,2011,2012 J. Ali Harlow et al" + VALUE "OriginalFilename","update.exe" + VALUE "ProductName","plover" + VALUE "ProductVersion","@PACKAGE_VERSION@" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation",0x809,0x4B0 + } + } + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update.exe.manifest" diff -r 772ff096a326 -r 31fb35727621 update/update-res.rc.in --- a/update/update-res.rc.in Fri Jul 08 08:33:44 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -#include -#include - -#pragma code_page(65001) - -MAINICON ICON "update.ico" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@, - @PLOVER_MICRO_VERSION@,0 - PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@, - @PLOVER_MICRO_VERSION@,0 - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - { - BLOCK "StringFileInfo" - { - BLOCK "080904B0" - { - VALUE "CompanyName","The plover development team" - VALUE "FileDescription","Plover update program" - VALUE "FileVersion","@PACKAGE_VERSION@" - VALUE "InternalName","update" - VALUE "LegalCopyright", - "Copyright © 2009,2011,2012 J. Ali Harlow et al" - VALUE "OriginalFilename","update.exe" - VALUE "ProductName","plover" - VALUE "ProductVersion","@PACKAGE_VERSION@" - } - } - BLOCK "VarFileInfo" - { - VALUE "Translation",0x809,0x4B0 - } - } - -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "update.exe.manifest" diff -r 772ff096a326 -r 31fb35727621 update/update.c --- a/update/update.c Fri Jul 08 08:33:44 2016 +0100 +++ b/update/update.c Sat Jul 16 11:07:18 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011 J. Ali Harlow + * Copyright (C) 2009, 2011, 2016 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 @@ -18,6 +18,7 @@ #include #include +#include #include #include "config.h" #include "plover/plover.h" @@ -27,22 +28,85 @@ void update(const char *argv0) { - char *path; - gchar *s,*prefix; + char *yum_uri,*local_database,*active_database,*alternate_database; + gchar *s,*prefix,*distribution,*vendor_prefix; int ch; struct comps *comps; GError *error=NULL; - path=plover_get_program_directory(argv0); - s=g_strconcat(path,"/repodata/comps.xml",NULL); - comps=plover_comps_new_from_file(s); + s=plover_get_program(argv0); + yum_uri=razor_path_to_uri(s); + g_free(s); + s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL); + comps=plover_comps_new_from_uri(s,&error); + g_free(s); + if (g_error_matches(error,PLOVER_RAZOR_ERROR, + RAZOR_GENERAL_ERROR_UNSUPPORTED_ARCHIVE)) + { + g_clear_error(&error); + free(yum_uri); + s=plover_get_program_directory(argv0); + yum_uri=razor_path_to_uri(s); + g_free(s); + s=g_strconcat(yum_uri,"/repodata/comps.xml",NULL); + comps=plover_comps_new_from_uri(s,&error); + } if (!comps) { - perror(s); + fprintf(stderr,"%s\n",error->message); + g_error_free(error); exit(1); } - g_free(s); - prefix=plover_default_prefix_for_vendor(comps->vendor); - if (!plover_installed_files_match_prefix(prefix)) + prefix=plover_comps_get_default_prefix(comps); + if (prefix) + { + s=g_strconcat(prefix,"/var/lib/razor",NULL); + local_database=razor_path_to_uri(s); + g_free(s); + } + else + local_database=NULL; + switch(comps->database) + { + case COMPS_DATABASE_DISTRIBUTION_LOCAL: + active_database=local_database; + alternate_database=NULL; + break; + case COMPS_DATABASE_GLOBAL: + active_database=NULL; + alternate_database=local_database; + break; + } + if (prefix) + { + distribution=g_strdup(comps->distribution); + plover_comps_set_distribution(comps,NULL); + vendor_prefix=plover_comps_get_default_prefix(comps); + plover_comps_set_distribution(comps,distribution); + g_free(distribution); + razor_set_database_uri(alternate_database); + if (plover_installed_files_match_prefix(vendor_prefix)==1) + { + printf("There is an existing installation under %s\n" + "which is not compatible with this distribution. In order\n" + "to continue, the existing installation must be uninstalled.\n" + "Do you want to remove all packages in the existing installion? ", + prefix); + ch=getchar(); + if (ch!='y' && ch!='Y' && ch!=EOF && ch!='\n') + exit(1); + while(ch!='\n' && ch!=EOF) + ch=getchar(); + if (plover_remove(NULL,&error)) + { + fprintf(stderr,"%s\n",error->message); + g_error_free(error); + exit(1); + } + } + g_free(vendor_prefix); + } + razor_set_database_uri(active_database); + if (prefix && !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" @@ -59,15 +123,16 @@ exit(1); } } + free(local_database); plover_comps_free(comps); - if (!plover_update(path,prefix,NULL,&error)) + if (!plover_update_uri(yum_uri,prefix,NULL,&error)) { fprintf(stderr,"%s\n",error->message); g_error_free(error); exit(1); } g_free(prefix); - free(path); + free(yum_uri); } int main(int argc,char **argv) diff -r 772ff096a326 -r 31fb35727621 update/update.manifest.in --- a/update/update.manifest.in Fri Jul 08 08:33:44 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -changequote([,])dnl - - - - Plover update program - - - - - - - - - - - - - - diff -r 772ff096a326 -r 31fb35727621 update/updatez-res.rc.in --- a/update/updatez-res.rc.in Fri Jul 08 08:33:44 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -#include -#include - -#pragma code_page(65001) - -MAINICON ICON "update.ico" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@, - @PLOVER_MICRO_VERSION@,0 - PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@, - @PLOVER_MICRO_VERSION@,0 - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - { - BLOCK "StringFileInfo" - { - BLOCK "080904B0" - { - VALUE "CompanyName","The plover development team" - VALUE "FileDescription","Plover update program" - VALUE "FileVersion","@PACKAGE_VERSION@" - VALUE "InternalName","updatez" - VALUE "LegalCopyright", - "Copyright © 2009,2011,2012 J. Ali Harlow et al" - VALUE "OriginalFilename","updatez.exe" - VALUE "ProductName","plover" - VALUE "ProductVersion","@PACKAGE_VERSION@" - } - } - BLOCK "VarFileInfo" - { - VALUE "Translation",0x809,0x4B0 - } - } - -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "updatez.exe.manifest" diff -r 772ff096a326 -r 31fb35727621 update/updatez.c --- a/update/updatez.c Fri Jul 08 08:33:44 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2009, 2011, 2016 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include "config.h" -#include "plover/plover.h" -#include "whelk/whelk.h" - -LUALIB_API int luaopen_posix(lua_State *L); - -void update_from_executable_zip(const char *argv0) -{ - char *uri; - gchar *s,*prefix; - int ch; - struct comps *comps; - GError *error=NULL; - s=plover_get_program(argv0); - uri=g_strconcat("file:",s,NULL); - g_free(s); - s=g_strconcat(uri,"/repodata/comps.xml",NULL); - comps=plover_comps_new_from_uri(s); - if (!comps) - { - perror(s); - exit(1); - } - g_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(); - if (plover_remove(NULL,&error)) - { - fprintf(stderr,"%s\n",error->message); - g_error_free(error); - exit(1); - } - } - plover_comps_free(comps); - if (!plover_update_uri(uri,prefix,NULL,&error)) - { - fprintf(stderr,"%s\n",error->message); - g_error_free(error); - exit(1); - } - g_free(prefix); - free(uri); -} - -int main(int argc,char **argv) -{ - plover_exception_handler_init(); - razor_set_lua_loader("posix",(void (*)())luaopen_posix); - razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); - update_from_executable_zip(argv[0]); - exit(0); -} diff -r 772ff096a326 -r 31fb35727621 update/updatez.manifest.in --- a/update/updatez.manifest.in Fri Jul 08 08:33:44 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -changequote([,])dnl - - - - Plover update program - - - - - - - - - - - - - -