1.1 --- a/.gitignore Fri Mar 23 20:29:50 2012 +0000
1.2 +++ b/.gitignore Sat Nov 15 19:04:45 2014 +0000
1.3 @@ -13,10 +13,26 @@
1.4 *.o
1.5 *.lo
1.6 *.la
1.7 +*.ico
1.8 +*.exe
1.9 +*.exe.manifest
1.10 plover/plover.pc
1.11 plover-gtk/plover-gtk.pc
1.12 setup/resources.rc
1.13 setup/setup
1.14 +setup/setup.js
1.15 +setup/icon*.pnm
1.16 update/resources.rc
1.17 update/update
1.18 +update/update.js
1.19 +update/icon*.pnm
1.20 +pre-inst/resources.rc
1.21 +pre-inst/pre-inst
1.22 +pre-inst/icon*.pnm
1.23 app-manager/resources.rc
1.24 +app-manager/fetch
1.25 +app-manager/app-manager
1.26 +app-manager/plover-applications*.pgm
1.27 +app-manager/plover-applications*.pnm
1.28 +app-manager/24x24
1.29 +app-manager/48x48
2.1 --- a/Makefile.am Fri Mar 23 20:29:50 2012 +0000
2.2 +++ b/Makefile.am Sat Nov 15 19:04:45 2014 +0000
2.3 @@ -1,1 +1,1 @@
2.4 -SUBDIRS=plover setup update plover-gtk app-manager
2.5 +SUBDIRS=plover setup update pre-inst plover-gtk app-manager
3.1 --- a/app-manager/Makefile.am Fri Mar 23 20:29:50 2012 +0000
3.2 +++ b/app-manager/Makefile.am Sat Nov 15 19:04:45 2014 +0000
3.3 @@ -3,12 +3,15 @@
3.4
3.5 bin_PROGRAMS=app-manager fetch
3.6 app_manager_SOURCES=app-manager.c app-manager.h packagelist.c applications.c \
3.7 - localmedia.c localmedia.h
3.8 + localmedia.c localmedia.h setup.c update.c
3.9 fetch_SOURCES=fetch.c
3.10 fetch_LDADD=$(LDADD) $(FETCH_LIBS)
3.11 if HAVE_WINDRES
3.12 app_manager_SOURCES+=resources.rc app-manager.exe.manifest
3.13 endif
3.14 +if PLOVER_MINGW
3.15 +app_manager_LDFLAGS=-mwindows
3.16 +endif
3.17 uidir=$(pkgdatadir)
3.18 ui_DATA=app-manager.ui
3.19 desktopdir=$(datadir)/applications
3.20 @@ -20,34 +23,39 @@
3.21 bigicondir=$(datadir)/icons/hicolor/48x48/apps
3.22 bigicon_DATA=48x48/plover-applications.png
3.23
3.24 +# PLOVER_V_SKIP: Don't echo anything for this command if V=0
3.25 +PLOVER_V_SKIP = $(PLOVER_V_SKIP_$(V))
3.26 +PLOVER_V_SKIP_ = $(PLOVER_V_SKIP_$(AM_DEFAULT_VERBOSITY))
3.27 +PLOVER_V_SKIP_0 = @
3.28 +
3.29 .rc.$(OBJEXT):
3.30 - $(WINDRES) $< $@
3.31 + $(AM_V_GEN)$(WINDRES) $< $@
3.32
3.33 resources.$(OBJEXT): app-manager.ico app-manager.exe.manifest
3.34
3.35 plover-applications%.pnm: plover-applications.svg
3.36 - rsvg -w $* -h $* -f png $< temp.png
3.37 - pngtopnm temp.png | pnmquant 256 > $@
3.38 - $(RM) temp.png
3.39 + $(PLOVER_V_SKIP)rsvg -w $* -h $* -f png $< temp.png
3.40 + $(AM_V_GEN)pngtopnm temp.png | pnmquant -quiet 256 > $@
3.41 + $(PLOVER_V_SKIP)$(RM) temp.png
3.42
3.43 plover-applications%.pgm: plover-applications.svg
3.44 - rsvg -w $* -h $* -f png $< temp.png
3.45 - pngtopnm -alpha temp.png > $@
3.46 - $(RM) temp.png
3.47 + $(PLOVER_V_SKIP)rsvg -w $* -h $* -f png $< temp.png
3.48 + $(AM_V_GEN)pngtopnm -alpha temp.png > $@
3.49 + $(PLOVER_V_SKIP)$(RM) temp.png
3.50
3.51 24x24/plover-applications.png: plover-applications.svg
3.52 - mkdir -p 24x24
3.53 - rsvg -w 24 -h 24 -f png $< $@
3.54 + $(PLOVER_V_SKIP)mkdir -p 24x24
3.55 + $(AM_V_GEN)rsvg -w 24 -h 24 -f png $< $@
3.56
3.57 48x48/plover-applications.png: plover-applications.svg
3.58 - mkdir -p 48x48
3.59 - rsvg -w 48 -h 48 -f png $< $@
3.60 + $(PLOVER_V_SKIP)mkdir -p 48x48
3.61 + $(AM_V_GEN)rsvg -w 48 -h 48 -f png $< $@
3.62
3.63 app-manager.ico: plover-applications16.pnm plover-applications16.pgm \
3.64 plover-applications22.pnm plover-applications22.pgm \
3.65 plover-applications32.pnm plover-applications32.pgm \
3.66 plover-applications46.pnm plover-applications46.pgm
3.67 - ppmtowinicon -andpgms -output=$@ $^
3.68 + $(AM_V_GEN)ppmtowinicon -andpgms -output=$@ $^
3.69
3.70 clean-local:
3.71 -rm -rf 24x24 48x48
4.1 --- a/app-manager/app-manager.c Fri Mar 23 20:29:50 2012 +0000
4.2 +++ b/app-manager/app-manager.c Sat Nov 15 19:04:45 2014 +0000
4.3 @@ -19,13 +19,21 @@
4.4 #include "config.h"
4.5 #include <stdlib.h>
4.6 #include <string.h>
4.7 +#ifdef WIN32
4.8 +#include <windows.h>
4.9 +#endif /* WIN32 */
4.10 +#include <lua.h>
4.11 #include <glib.h>
4.12 #include <gio/gio.h>
4.13 #include <gtk/gtk.h>
4.14 -#include <plover-gtk/packageset.h>
4.15 +#include <whelk/whelk.h>
4.16 +#include <plover/packageset.h>
4.17 +#include <plover-gtk/stockicons.h>
4.18 #include "app-manager.h"
4.19 #include "localmedia.h"
4.20
4.21 +LUALIB_API int luaopen_posix(lua_State *L);
4.22 +
4.23 #define LOGO_NAME "plover-applications"
4.24
4.25 GtkBuilder *ui;
4.26 @@ -103,6 +111,7 @@
4.27 }
4.28 }
4.29
4.30 +#if 0
4.31 /* Checks whether a loader for SVG files has been registered
4.32 * with GdkPixbuf.
4.33 */
4.34 @@ -191,21 +200,61 @@
4.35 icon_set=gtk_icon_factory_lookup_default(LOGO_NAME);
4.36 gtk_window_set_default_icon_name(LOGO_NAME);
4.37 }
4.38 +#endif
4.39 +
4.40 +static void install_icons(void)
4.41 +{
4.42 + GtkIconSet *icon_set;
4.43 + plover_icons_add_to_stock("apps",LOGO_NAME);
4.44 + icon_set=gtk_icon_factory_lookup_default(LOGO_NAME);
4.45 + gtk_window_set_default_icon_name(LOGO_NAME);
4.46 +}
4.47
4.48 int main(int argc,char **argv)
4.49 {
4.50 GError *err=0;
4.51 GtkWidget *w;
4.52 gchar *s,*contents;
4.53 + gchar *setup_base=NULL,*update_base=NULL;
4.54 gsize len;
4.55 PloverPackageSet *set;
4.56 + GSList *objects,*lnk;
4.57 + gboolean started;
4.58 GOptionEntry options[]={
4.59 + {"setup",0,0,G_OPTION_ARG_FILENAME,&setup_base,
4.60 + "Setup from installation media","path"},
4.61 + {"update",0,0,G_OPTION_ARG_FILENAME,&update_base,
4.62 + "Update from upgrade media","path"},
4.63 {NULL}
4.64 };
4.65 +#ifdef WIN32
4.66 + /*
4.67 + * app-manager is normally a GUI application, but rpm scripts may well
4.68 + * call console applications and it looks ugly if console windows keep
4.69 + * popping up. Avoid this by allocating our own console and hiding it.
4.70 + * Note:
4.71 + * - If app-manager is a console application (typically for debugging),
4.72 + * then skip this step.
4.73 + * - Call ShowWindow twice to negate special handling on first call.
4.74 + */
4.75 + if (!GetConsoleWindow())
4.76 + {
4.77 + AllocConsole();
4.78 + ShowWindow(GetConsoleWindow(),SW_HIDE);
4.79 + ShowWindow(GetConsoleWindow(),SW_HIDE);
4.80 + }
4.81 +#endif
4.82 + razor_set_lua_loader("posix",luaopen_posix);
4.83 + razor_set_lua_loader("whelk",luaopen_whelk);
4.84 if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
4.85 {
4.86 - g_printerr("%s",err->message);
4.87 - exit(0);
4.88 + g_printerr("%s\n",err->message);
4.89 + exit(1);
4.90 + }
4.91 + if (setup_base && update_base)
4.92 + {
4.93 + g_printerr("--setup and --update are mutually exclusive\n");
4.94 + exit(1);
4.95 }
4.96 #ifdef WIN32
4.97 prefix=g_win32_get_package_installation_directory_of_module(NULL);
4.98 @@ -242,23 +291,45 @@
4.99 gtk_builder_connect_signals(ui,NULL);
4.100 gtk_link_button_set_uri_hook(show_uri,NULL,NULL);
4.101 installed=GTK_TREE_MODEL(plover_package_store_new());
4.102 - set=plover_package_set_new_from_installed("",NULL);
4.103 - if (set)
4.104 + set=plover_package_set_new();
4.105 + (void)plover_package_set_open(set,"",TRUE,NULL);
4.106 + plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set);
4.107 + if (plover_package_set_get_no_details(set))
4.108 {
4.109 - plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set);
4.110 - if (plover_package_set_get_no_details(set))
4.111 - {
4.112 - w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles"));
4.113 - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE);
4.114 - }
4.115 + w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles"));
4.116 + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE);
4.117 }
4.118 applications=plover_applications_model_new(installed);
4.119 set_package_model(applications);
4.120 - gtk_main();
4.121 - g_object_unref(ui);
4.122 + if (setup_base)
4.123 + started=setup(set,setup_base);
4.124 + else if (update_base)
4.125 + started=update(set,update_base);
4.126 + else
4.127 + {
4.128 + w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
4.129 + gtk_widget_show(w);
4.130 + started=TRUE;
4.131 + }
4.132 + if (started)
4.133 + gtk_main();
4.134 + g_clear_object(&set);
4.135 + objects=gtk_builder_get_objects(ui);
4.136 + for(lnk=objects;lnk;lnk=lnk->next)
4.137 + if (GTK_IS_WIDGET(lnk->data) &&
4.138 + gtk_widget_is_toplevel(GTK_WIDGET(lnk->data)))
4.139 + gtk_widget_destroy(GTK_WIDGET(lnk->data));
4.140 + g_slist_free(objects);
4.141 + g_clear_object(&ui);
4.142 + g_clear_object(&installed);
4.143 + g_clear_object(&applications);
4.144 + g_clear_object(&location);
4.145 + g_clear_object(&local_media);
4.146 if (relocations)
4.147 razor_relocations_destroy(relocations);
4.148 g_free(prefix);
4.149 + g_free(setup_base);
4.150 + g_free(update_base);
4.151 exit(0);
4.152 }
4.153
4.154 @@ -323,7 +394,7 @@
4.155 {
4.156 show_busy_cursor(TRUE);
4.157 path=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
4.158 - set=plover_package_set_new_from_repository(path,relocations,&err);
4.159 + set=plover_package_set_new_from_yum(path,relocations,&err);
4.160 if (set)
4.161 {
4.162 if (!location)
4.163 @@ -399,7 +470,8 @@
4.164 GtkWidget *w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
4.165 gtk_show_about_dialog(GTK_WINDOW(w),"name",PACKAGE_NAME,
4.166 "version",PACKAGE_VERSION,"comments","Application Manager",
4.167 - "copyright","Copyright © 2010 J. Ali Harlow","logo-icon-name",LOGO_NAME,
4.168 + "copyright","Copyright © 2010, 2014 J. Ali Harlow",
4.169 + "logo-icon-name",LOGO_NAME,
4.170 NULL);
4.171 }
4.172
5.1 --- a/app-manager/app-manager.h Fri Mar 23 20:29:50 2012 +0000
5.2 +++ b/app-manager/app-manager.h Sat Nov 15 19:04:45 2014 +0000
5.3 @@ -1,9 +1,11 @@
5.4 #include <razor.h>
5.5 #include <gtk/gtk.h>
5.6 -#include <plover-gtk/package.h>
5.7 +#include <plover/package.h>
5.8
5.9 extern GtkBuilder *ui;
5.10 extern struct razor_relocations *relocations;
5.11 GtkTreeModel *plover_applications_model_new(GtkTreeModel *installed);
5.12 void set_package_model(GtkTreeModel *model);
5.13 PloverPackage *get_active_package(void);
5.14 +gboolean setup(PloverPackageSet *current,const char *base);
5.15 +gboolean update(PloverPackageSet *current,const char *base);
6.1 --- a/app-manager/app-manager.ui Fri Mar 23 20:29:50 2012 +0000
6.2 +++ b/app-manager/app-manager.ui Sat Nov 15 19:04:45 2014 +0000
6.3 @@ -1,9 +1,8 @@
6.4 <?xml version="1.0"?>
6.5 <interface>
6.6 <requires lib="gtk+" version="2.16"/>
6.7 - <!-- interface-naming-policy toplevel-contextual -->
6.8 + <!-- interface-naming-policy project-wide -->
6.9 <object class="GtkWindow" id="MainWindow">
6.10 - <property name="visible">True</property>
6.11 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
6.12 <property name="title" translatable="yes">Application Manager</property>
6.13 <property name="default_width">600</property>
6.14 @@ -368,7 +367,7 @@
6.15 </packing>
6.16 </child>
6.17 <child>
6.18 - <object class="GtkAlignment" id="alignment2">
6.19 + <object class="GtkAlignment" id="alignment3">
6.20 <property name="visible">True</property>
6.21 <property name="left_padding">6</property>
6.22 <property name="right_padding">6</property>
7.1 --- a/app-manager/applications.c Fri Mar 23 20:29:50 2012 +0000
7.2 +++ b/app-manager/applications.c Sat Nov 15 19:04:45 2014 +0000
7.3 @@ -25,6 +25,7 @@
7.4 #include <glib.h>
7.5 #include <gtk/gtk.h>
7.6 #include <plover-gtk/packagestore.h>
7.7 +#include <plover-gtk/packagefilestore.h>
7.8 #include "app-manager.h"
7.9
7.10 #ifdef WIN32
7.11 @@ -63,7 +64,8 @@
7.12 gtk_tree_model_get(model,iter,PLOVER_PACKAGE_STORE_OBJ_COLUMN,&package,-1);
7.13 if (package)
7.14 {
7.15 - file_store=GTK_TREE_MODEL(plover_package_get_file_store(package));
7.16 + file_store=
7.17 + GTK_TREE_MODEL(plover_package_file_store_new_from_package(package));
7.18 if (gtk_tree_model_get_iter_first(file_store,&fi))
7.19 {
7.20 do
7.21 @@ -94,6 +96,7 @@
7.22 g_free(name);
7.23 } while(!visible && gtk_tree_model_iter_next(file_store,&fi));
7.24 }
7.25 + g_object_unref(file_store);
7.26 }
7.27 g_object_unref(package);
7.28 return visible;
8.1 --- a/app-manager/fetch.c Fri Mar 23 20:29:50 2012 +0000
8.2 +++ b/app-manager/fetch.c Sat Nov 15 19:04:45 2014 +0000
8.3 @@ -158,7 +158,7 @@
8.4 const char *name;
8.5 char *install_root;
8.6 struct razor_set *set;
8.7 - struct razor_atomic *atomic;
8.8 + struct razor_error *error=NULL;
8.9 struct razor_package *package;
8.10 struct razor_package_iterator *pi;
8.11 struct razor_file_iterator *fi;
8.12 @@ -167,8 +167,7 @@
8.13 install_root=getenv("RAZOR_ROOT");
8.14 if (!install_root)
8.15 install_root="";
8.16 - atomic=razor_atomic_open("Query packages");
8.17 - set=razor_root_open_read_only(install_root,atomic);
8.18 + set=razor_root_open_read_only(install_root,&error);
8.19 if (set)
8.20 {
8.21 pi=razor_package_iterator_create(set);
8.22 @@ -192,7 +191,8 @@
8.23 razor_package_iterator_destroy(pi);
8.24 razor_set_unref(set);
8.25 }
8.26 - razor_atomic_destroy(atomic);
8.27 + if (error)
8.28 + razor_error_free(error);
8.29 return retval;
8.30 }
8.31
9.1 --- a/app-manager/localmedia.c Fri Mar 23 20:29:50 2012 +0000
9.2 +++ b/app-manager/localmedia.c Sat Nov 15 19:04:45 2014 +0000
9.3 @@ -90,7 +90,7 @@
9.4 #endif
9.5 if (path)
9.6 {
9.7 - set=plover_package_set_new_from_repository(path,relocations,NULL);
9.8 + set=plover_package_set_new_from_yum(path,relocations,NULL);
9.9 if (set)
9.10 {
9.11 g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set);
10.1 --- a/app-manager/packagelist.c Fri Mar 23 20:29:50 2012 +0000
10.2 +++ b/app-manager/packagelist.c Sat Nov 15 19:04:45 2014 +0000
10.3 @@ -20,8 +20,8 @@
10.4 #include <stdlib.h>
10.5 #include <string.h>
10.6 #include <gtk/gtk.h>
10.7 -#include <plover-gtk/package.h>
10.8 -#include <plover-gtk/packageset.h>
10.9 +#include <plover/package.h>
10.10 +#include <plover/packageset.h>
10.11 #include <plover-gtk/packagestore.h>
10.12 #include <plover-gtk/packagefilestore.h>
10.13 #include "app-manager.h"
10.14 @@ -36,6 +36,7 @@
10.15 const char *text,*t;
10.16 GtkWidget *w;
10.17 GtkTextBuffer *buf;
10.18 + PloverPackageFileStore *store;
10.19 buf=GTK_TEXT_BUFFER(gtk_builder_get_object(ui,"description"));
10.20 if (package)
10.21 {
10.22 @@ -97,8 +98,9 @@
10.23 {
10.24 gtk_widget_hide(w);
10.25 w=GTK_WIDGET(gtk_builder_get_object(ui,"Files"));
10.26 - gtk_tree_view_set_model(GTK_TREE_VIEW(w),
10.27 - GTK_TREE_MODEL(plover_package_get_file_store(package)));
10.28 + store=plover_package_file_store_new_from_package(package);
10.29 + gtk_tree_view_set_model(GTK_TREE_VIEW(w),GTK_TREE_MODEL(store));
10.30 + g_object_unref(store);
10.31 }
10.32 else
10.33 {
11.1 --- a/app-manager/resources.rc.in Fri Mar 23 20:29:50 2012 +0000
11.2 +++ b/app-manager/resources.rc.in Sat Nov 15 19:04:45 2014 +0000
11.3 @@ -1,6 +1,8 @@
11.4 #include <winver.h>
11.5 #include <winuser.h>
11.6
11.7 +#pragma code_page(65001)
11.8 +
11.9 MAINICON ICON "app-manager.ico"
11.10
11.11 VS_VERSION_INFO VERSIONINFO
11.12 @@ -31,3 +33,5 @@
11.13 VALUE "Translation",0x809,0x4B0
11.14 }
11.15 }
11.16 +
11.17 +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app-manager.exe.manifest"
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/app-manager/setup.c Sat Nov 15 19:04:45 2014 +0000
12.3 @@ -0,0 +1,88 @@
12.4 +/*
12.5 + * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
12.6 + *
12.7 + * This program is free software; you can redistribute it and/or modify
12.8 + * it under the terms of the GNU General Public License as published by
12.9 + * the Free Software Foundation; either version 2 of the License, or
12.10 + * (at your option) any later version.
12.11 + *
12.12 + * This program is distributed in the hope that it will be useful,
12.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.15 + * GNU General Public License for more details.
12.16 + *
12.17 + * You should have received a copy of the GNU General Public License along
12.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
12.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
12.20 + */
12.21 +
12.22 +#include "config.h"
12.23 +#include <stdlib.h>
12.24 +#include <string.h>
12.25 +#include <errno.h>
12.26 +#include <glib.h>
12.27 +#include <gio/gio.h>
12.28 +#include <gtk/gtk.h>
12.29 +#include <plover/plover.h>
12.30 +#include <plover/transaction.h>
12.31 +#include <plover/packageset.h>
12.32 +#include <plover-gtk/transactionhelper.h>
12.33 +#include "app-manager.h"
12.34 +
12.35 +gboolean setup(PloverPackageSet *installed,const char *base)
12.36 +{
12.37 + gchar *s;
12.38 + const char *prefix;
12.39 + GError *error=NULL;
12.40 + static PloverTransactionHelper *helper=NULL;
12.41 + if (!helper)
12.42 + {
12.43 + helper=plover_transaction_helper_new(ui);
12.44 + plover_transaction_helper_set_installed(helper,installed);
12.45 + plover_transaction_helper_set_base(helper,base);
12.46 + prefix=plover_transaction_helper_get_prefix(helper,&error);
12.47 + if (error)
12.48 + g_clear_error(&error);
12.49 + else
12.50 + {
12.51 + s=g_strconcat(prefix?prefix:"","/var/log/setup",NULL);
12.52 + plover_log_open(s);
12.53 + g_free(s);
12.54 + }
12.55 + plover_transaction_helper_set_check_vendor(helper,TRUE);
12.56 + g_signal_connect(helper,"close",G_CALLBACK(gtk_main_quit),NULL);
12.57 + }
12.58 + if (!plover_transaction_helper_get_visible(helper))
12.59 + {
12.60 + if (!plover_transaction_helper_install_group(helper,"base",&error))
12.61 + {
12.62 + if (g_error_matches(error,PLOVER_GENERAL_ERROR,
12.63 + PLOVER_GENERAL_ERROR_NO_WORK))
12.64 + {
12.65 + g_error_free(error);
12.66 + error=g_error_new_literal(PLOVER_GENERAL_ERROR,
12.67 + PLOVER_GENERAL_ERROR_NO_WORK,
12.68 + "All packages already installed");
12.69 + plover_transaction_helper_set_error(helper,error,
12.70 + "Software installation");
12.71 + }
12.72 + else if (g_error_matches(error,PLOVER_GENERAL_ERROR,
12.73 + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET))
12.74 + {
12.75 + g_error_free(error);
12.76 + error=g_error_new_literal(PLOVER_GENERAL_ERROR,
12.77 + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET,
12.78 + "Software cannot be installed because of missing updates. "
12.79 + "Installing all updates first should resolve this problem");
12.80 + plover_transaction_helper_set_error(helper,error,
12.81 + "Software installation failed");
12.82 + }
12.83 + else
12.84 + plover_transaction_helper_set_error(helper,error,
12.85 + "Software installation failed");
12.86 + g_error_free(error);
12.87 + }
12.88 + }
12.89 + plover_transaction_helper_present(helper);
12.90 + return TRUE;
12.91 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/app-manager/update.c Sat Nov 15 19:04:45 2014 +0000
13.3 @@ -0,0 +1,89 @@
13.4 +/*
13.5 + * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
13.6 + *
13.7 + * This program is free software; you can redistribute it and/or modify
13.8 + * it under the terms of the GNU General Public License as published by
13.9 + * the Free Software Foundation; either version 2 of the License, or
13.10 + * (at your option) any later version.
13.11 + *
13.12 + * This program is distributed in the hope that it will be useful,
13.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.15 + * GNU General Public License for more details.
13.16 + *
13.17 + * You should have received a copy of the GNU General Public License along
13.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
13.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
13.20 + */
13.21 +
13.22 +#include "config.h"
13.23 +#include <stdlib.h>
13.24 +#include <string.h>
13.25 +#include <errno.h>
13.26 +#include <glib.h>
13.27 +#include <gio/gio.h>
13.28 +#include <gtk/gtk.h>
13.29 +#include <plover/plover.h>
13.30 +#include <plover/transaction.h>
13.31 +#include <plover/packageset.h>
13.32 +#include <plover-gtk/transactionhelper.h>
13.33 +#include "app-manager.h"
13.34 +
13.35 +gboolean update(PloverPackageSet *installed,const char *base)
13.36 +{
13.37 + gchar *s;
13.38 + const char *prefix;
13.39 + GError *error=NULL;
13.40 + static PloverTransactionHelper *helper=NULL;
13.41 + if (!helper)
13.42 + {
13.43 + helper=plover_transaction_helper_new(ui);
13.44 + plover_transaction_helper_set_installed(helper,installed);
13.45 + plover_transaction_helper_set_base(helper,base);
13.46 + prefix=plover_transaction_helper_get_prefix(helper,&error);
13.47 + if (error)
13.48 + g_clear_error(&error);
13.49 + else
13.50 + {
13.51 + s=g_strconcat(prefix?prefix:"","/var/log/update",NULL);
13.52 + plover_log_open(s);
13.53 + g_free(s);
13.54 + }
13.55 + plover_transaction_helper_set_check_vendor(helper,TRUE);
13.56 + g_signal_connect(helper,"close",G_CALLBACK(gtk_main_quit),NULL);
13.57 + }
13.58 + if (!plover_transaction_helper_get_visible(helper))
13.59 + {
13.60 + if (!plover_transaction_helper_update(helper,&error))
13.61 + {
13.62 + if (g_error_matches(error,PLOVER_GENERAL_ERROR,
13.63 + PLOVER_GENERAL_ERROR_NO_WORK))
13.64 + {
13.65 + g_error_free(error);
13.66 + error=g_error_new_literal(PLOVER_GENERAL_ERROR,
13.67 + PLOVER_GENERAL_ERROR_NO_WORK,
13.68 + "All relevant updates already applied");
13.69 + plover_transaction_helper_set_error(helper,error,
13.70 + "Software update");
13.71 + }
13.72 + else if (g_error_matches(error,PLOVER_GENERAL_ERROR,
13.73 + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET))
13.74 + {
13.75 + g_error_free(error);
13.76 + error=g_error_new_literal(PLOVER_GENERAL_ERROR,
13.77 + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET,
13.78 + "Updates cannot be applied because some earlier updates are "
13.79 + "missing. Installing updates in sequence should resolve this "
13.80 + "problem");
13.81 + plover_transaction_helper_set_error(helper,error,
13.82 + "Software update failed");
13.83 + }
13.84 + else
13.85 + plover_transaction_helper_set_error(helper,error,
13.86 + "Software update failed");
13.87 + g_error_free(error);
13.88 + }
13.89 + }
13.90 + plover_transaction_helper_present(helper);
13.91 + return TRUE;
13.92 +}
14.1 --- a/configure.ac Fri Mar 23 20:29:50 2012 +0000
14.2 +++ b/configure.ac Sat Nov 15 19:04:45 2014 +0000
14.3 @@ -1,7 +1,7 @@
14.4 # -*- Autoconf -*-
14.5 # Process this file with autoconf to produce a configure script.
14.6
14.7 -AC_INIT([plover],[0.4.3],[ali@juiblex.co.uk])
14.8 +AC_INIT([plover],[0.4.50],[ali@juiblex.co.uk])
14.9 AC_PREREQ(2.59)
14.10 AC_CONFIG_AUX_DIR([config])
14.11 AC_CONFIG_SRCDIR([plover/plover.h])
14.12 @@ -15,14 +15,18 @@
14.13 setup/resources.rc
14.14 update/Makefile
14.15 update/resources.rc
14.16 +pre-inst/Makefile
14.17 +pre-inst/resources.rc
14.18 app-manager/Makefile
14.19 app-manager/resources.rc
14.20 ])
14.21 PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in
14.22 update/update.exe.manifest:update/manifest.xml.in
14.23 +pre-inst/pre-inst.exe.manifest:pre-inst/manifest.xml.in
14.24 app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in
14.25 ])
14.26 AM_INIT_AUTOMAKE(no-define)
14.27 +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
14.28 case $VERSION in
14.29 *.*.*)
14.30 AC_SUBST(PLOVER_MAJOR_VERSION,[[`echo $VERSION | sed 's/\..*//'`]])
14.31 @@ -44,6 +48,15 @@
14.32 AC_CANONICAL_HOST
14.33 AC_SUBST(HOST_OS,$host_os)
14.34 AC_SUBST(HOST_CPU,$host_cpu)
14.35 +case $host_os in
14.36 + mingw*)
14.37 + host_mingw="yes"
14.38 + ;;
14.39 + *)
14.40 + host_mingw=""
14.41 + ;;
14.42 +esac
14.43 +AM_CONDITIONAL(PLOVER_MINGW,[test -n "$host_mingw"])
14.44
14.45 # libtool versioning for libplover. For a release one of the following
14.46 # must apply:
14.47 @@ -54,7 +67,7 @@
14.48 # increment CURRENT and set AGE and REVISION to 0.
14.49 # - If the interface is the same as the previous version, increment REVISION.
14.50 #
14.51 -lt_current=2
14.52 +lt_current=3
14.53 lt_revision=0
14.54 lt_age=0
14.55 LIBPLOVER_LT_VERSION_INFO="$lt_current:$lt_revision:$lt_age"
14.56 @@ -93,32 +106,44 @@
14.57 ##################################################
14.58 # Checks for libraries.
14.59 ##################################################
14.60 +PKG_CHECK_MODULES(WHELK,[whelk])
14.61 PKG_CHECK_MODULES(RAZOR,[razor >= 0.5.4],[:],[RAZOR_LIBS=-lrazor])
14.62 PKG_CHECK_MODULES(EXPAT,[expat],[:],[EXPAT_LIBS=-lexpat])
14.63 PKG_CHECK_MODULES(ZLIB,[zlib],[:],[ZLIB_LIBS=-lz])
14.64 PKG_CHECK_MODULES(GIO,[gio-2.0])
14.65 PKG_CHECK_MODULES(GTK,[gtk+-2.0])
14.66 PKG_CHECK_MODULES(GMODULE_EXPORT,[gmodule-export-2.0])
14.67 -LIBPLOVER_CFLAGS="$RAZOR_CFLAGS $EXPAT_CFLAGS $ZLIB_CFLAGS"
14.68 -LIBPLOVER_LIBS="$RAZOR_LIBS $EXPAT_LIBS $ZLIB_LIBS"
14.69 +LIBPLOVER_CFLAGS="$RAZOR_CFLAGS $EXPAT_CFLAGS $ZLIB_CFLAGS $GIO_CFLAGS"
14.70 +LIBPLOVER_LIBS="$RAZOR_LIBS $EXPAT_LIBS $ZLIB_LIBS $GIO_LIBS"
14.71 AC_SUBST(LIBPLOVER_CFLAGS)
14.72 AC_SUBST(LIBPLOVER_LIBS)
14.73 PLOVER_GTK_CFLAGS="$GTK_CFLAGS $RAZOR_CFLAGS"
14.74 PLOVER_GTK_LIBS="$GTK_LIBS $RAZOR_LIBS"
14.75 AC_SUBST(PLOVER_GTK_CFLAGS)
14.76 AC_SUBST(PLOVER_GTK_LIBS)
14.77 -GUI_CFLAGS="$GMODULE_EXPORT_CFLAGS $GIO_CFLAGS $PLOVER_GTK_CFLAGS $LIBPLOVER_CFLAGS"
14.78 -GUI_LIBS="$GMODULE_EXPORT_LIBS $GIO_LIBS $PLOVER_GTK_LIBS $LIBPLOVER_LIBS"
14.79 +save_LIBS="$LIBS"
14.80 +AC_SEARCH_LIBS([crypt],[crypt])
14.81 +GUI_CFLAGS="$GMODULE_EXPORT_CFLAGS $WHELK_CFLAGS $PLOVER_GTK_CFLAGS \
14.82 + $LIBPLOVER_CFLAGS"
14.83 +GUI_LIBS="-llua-posix $GMODULE_EXPORT_LIBS $WHELK_LIBS $PLOVER_GTK_LIBS \
14.84 + $LIBPLOVER_LIBS $LIBS"
14.85 +LIBS="$save_LIBS"
14.86 AC_SUBST(GUI_CFLAGS)
14.87 AC_SUBST(GUI_LIBS)
14.88 save_PKG_CONFIG="$PKG_CONFIG"
14.89 PKG_CONFIG="$PKG_CONFIG --static"
14.90 -PKG_CHECK_MODULES(SETUP,[whelk])
14.91 +PKG_CHECK_MODULES(SETUP,[whelk razor >= 0.5.4 expat zlib gio-2.0])
14.92 +if test -n "$host_mingw"; then
14.93 + # Hack: -liconv is required for mingw. This probably stems from our use of
14.94 + # libiconv rather than win-iconv that Fedora uses, but should be addressed
14.95 + # somewhere in the stack below us.
14.96 + SETUP_LIBS="$SETUP_LIBS -liconv"
14.97 +fi
14.98 PKG_CONFIG="$save_PKG_CONFIG"
14.99 save_LIBS="$LIBS"
14.100 AC_SEARCH_LIBS([crypt],[crypt])
14.101 -SETUP_LIBS="-llua-posix $SETUP_LIBS $RAZOR_LIBS $LIBS"
14.102 -SETUP_CFLAGS="$SETUP_CFLAGS $RAZOR_CFLAGS"
14.103 +SETUP_LIBS="-llua-posix $SETUP_LIBS $LIBS"
14.104 +SETUP_CFLAGS="$SETUP_CFLAGS"
14.105 AC_SUBST(SETUP_LIBS)
14.106 AC_SUBST(SETUP_CFLAGS)
14.107 LIBS="$save_LIBS"
14.108 @@ -139,7 +164,7 @@
14.109 ##################################################
14.110 # Checks for library functions.
14.111 ##################################################
14.112 -AC_CHECK_FUNCS_ONCE([fchdir])
14.113 +AC_CHECK_FUNCS_ONCE([fchdir fpathconf dirfd])
14.114
14.115 ##################################################
14.116 # Checks for processor independent files.
15.1 --- a/plover-gtk/Makefile.am Fri Mar 23 20:29:50 2012 +0000
15.2 +++ b/plover-gtk/Makefile.am Sat Nov 15 19:04:45 2014 +0000
15.3 @@ -1,15 +1,19 @@
15.4 -AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS)
15.5 +AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS) -DPLOVER_DATADIR=\""$(pkgdatadir)"\"
15.6 LIBS=../plover/libplover.la $(PLOVER_GTK_LIBS)
15.7 INCLUDES=-I$(top_srcdir)
15.8 AM_LDFLAGS=-no-undefined -version-info $(PLOVER_GTK_LT_VERSION_INFO)
15.9
15.10 -pkginclude_HEADERS=error.h package.h packageset.h packagestore.h \
15.11 - packagefilestore.h
15.12 +uidir=$(pkgdatadir)
15.13 +ui_DATA=software-installation.ui
15.14 +
15.15 +pkginclude_HEADERS=\
15.16 + transactionhelper.h packagestore.h packagefilestore.h stockicons.h
15.17
15.18 lib_LTLIBRARIES=libplover-gtk.la
15.19 libplover_gtk_la_SOURCES=$(pkginclude_HEADERS) \
15.20 - error.c package.c packageset.c packagestore.c \
15.21 - packagefilestore.c
15.22 + transactionhelper.c packagestore.c packagefilestore.c stockicons.c
15.23
15.24 pkgconfigdir=$(libdir)/pkgconfig
15.25 pkgconfig_DATA=plover-gtk.pc
15.26 +
15.27 +EXTRA_DIST=software-installation.ui
16.1 --- a/plover-gtk/error.c Fri Mar 23 20:29:50 2012 +0000
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,30 +0,0 @@
16.4 -/*
16.5 - * Copyright (C) 2010 J. Ali Harlow <ali@juiblex.co.uk>
16.6 - *
16.7 - * This program is free software; you can redistribute it and/or modify
16.8 - * it under the terms of the GNU General Public License as published by
16.9 - * the Free Software Foundation; either version 2 of the License, or
16.10 - * (at your option) any later version.
16.11 - *
16.12 - * This program is distributed in the hope that it will be useful,
16.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.15 - * GNU General Public License for more details.
16.16 - *
16.17 - * You should have received a copy of the GNU General Public License along
16.18 - * with this program; if not, write to the Free Software Foundation, Inc.,
16.19 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16.20 - */
16.21 -
16.22 -#include "config.h"
16.23 -#include <stdlib.h>
16.24 -#include <glib.h>
16.25 -
16.26 -GQuark plover_razor_error_quark(void)
16.27 -{
16.28 - static GQuark quark=0;
16.29 - if (!quark)
16.30 - quark=g_quark_from_static_string("plover-razor-error-quark");
16.31 - return quark;
16.32 -}
16.33 -
17.1 --- a/plover-gtk/error.h Fri Mar 23 20:29:50 2012 +0000
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,12 +0,0 @@
17.4 -#ifndef __PLOVER_ERROR_H__
17.5 -#define __PLOVER_ERROR_H__
17.6 -
17.7 -#define PLOVER_RAZOR_ERROR plover_razor_error_quark()
17.8 -
17.9 -typedef enum {
17.10 - PLOVER_RAZOR_ERROR_FAILED
17.11 -} PloverRazorError;
17.12 -
17.13 -GQuark plover_razor_error_quark(void);
17.14 -
17.15 -#endif /* __PLOVER_ERROR_H__ */
18.1 --- a/plover-gtk/package.c Fri Mar 23 20:29:50 2012 +0000
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,180 +0,0 @@
18.4 -/*
18.5 - * Copyright (C) 2010 J. Ali Harlow <ali@juiblex.co.uk>
18.6 - *
18.7 - * This program is free software; you can redistribute it and/or modify
18.8 - * it under the terms of the GNU General Public License as published by
18.9 - * the Free Software Foundation; either version 2 of the License, or
18.10 - * (at your option) any later version.
18.11 - *
18.12 - * This program is distributed in the hope that it will be useful,
18.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.15 - * GNU General Public License for more details.
18.16 - *
18.17 - * You should have received a copy of the GNU General Public License along
18.18 - * with this program; if not, write to the Free Software Foundation, Inc.,
18.19 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18.20 - */
18.21 -
18.22 -#include "config.h"
18.23 -#include <stdlib.h>
18.24 -#include <string.h>
18.25 -#include <glib-object.h>
18.26 -#include <gtk/gtk.h>
18.27 -#include <razor.h>
18.28 -#include "plover-gtk/package.h"
18.29 -
18.30 -G_DEFINE_TYPE(PloverPackage,plover_package,G_TYPE_OBJECT);
18.31 -
18.32 -typedef struct _PloverPackagePrivate {
18.33 - struct razor_set *set;
18.34 - struct razor_package *pkg;
18.35 - PloverPackageFileStore *file_store;
18.36 -} PloverPackagePrivate;
18.37 -
18.38 -#define PLOVER_PACKAGE_GET_PRIVATE(obj)\
18.39 - G_TYPE_INSTANCE_GET_PRIVATE(obj,\
18.40 - PLOVER_TYPE_PACKAGE,PloverPackagePrivate)
18.41 -
18.42 -enum {
18.43 - CHANGED=0,
18.44 - N_SIGNALS
18.45 -};
18.46 -
18.47 -static guint signals[N_SIGNALS];
18.48 -
18.49 -static void plover_package_dispose(GObject *obj)
18.50 -{
18.51 - PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj);
18.52 - if (priv->file_store)
18.53 - {
18.54 - g_object_unref(priv->file_store);
18.55 - priv->file_store=NULL;
18.56 - }
18.57 - if (G_OBJECT_CLASS(plover_package_parent_class)->dispose)
18.58 - G_OBJECT_CLASS(plover_package_parent_class)->dispose(obj);
18.59 -}
18.60 -
18.61 -static void plover_package_class_init(PloverPackageClass *klass)
18.62 -{
18.63 - GObjectClass *oclass=G_OBJECT_CLASS(klass);
18.64 - oclass->dispose=plover_package_dispose;
18.65 - g_type_class_add_private(klass,sizeof(PloverPackagePrivate));
18.66 - signals[CHANGED]=g_signal_newv("changed",
18.67 - G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
18.68 - g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
18.69 -}
18.70 -
18.71 -static void plover_package_init(PloverPackage *package)
18.72 -{
18.73 -}
18.74 -
18.75 -PloverPackage *plover_package_new(struct razor_set *set,
18.76 - struct razor_package *pkg)
18.77 -{
18.78 - PloverPackage *package;
18.79 - PloverPackagePrivate *priv;
18.80 - package=g_object_new(PLOVER_TYPE_PACKAGE,NULL);
18.81 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.82 - priv->set=set;
18.83 - priv->pkg=pkg;
18.84 - return package;
18.85 -}
18.86 -
18.87 -const char *plover_package_get_name(PloverPackage *package)
18.88 -{
18.89 - PloverPackagePrivate *priv;
18.90 - const char *name=NULL;
18.91 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.92 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.93 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_NAME,&name,
18.94 - RAZOR_DETAIL_LAST);
18.95 - return name;
18.96 -}
18.97 -
18.98 -const char *plover_package_get_summary(PloverPackage *package)
18.99 -{
18.100 - PloverPackagePrivate *priv;
18.101 - const char *summary=NULL;
18.102 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.103 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.104 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_SUMMARY,&summary,
18.105 - RAZOR_DETAIL_LAST);
18.106 - return summary;
18.107 -}
18.108 -
18.109 -const char *plover_package_get_version(PloverPackage *package)
18.110 -{
18.111 - PloverPackagePrivate *priv;
18.112 - const char *version=NULL;
18.113 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.114 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.115 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_VERSION,&version,
18.116 - RAZOR_DETAIL_LAST);
18.117 - return version;
18.118 -}
18.119 -
18.120 -const char *plover_package_get_license(PloverPackage *package)
18.121 -{
18.122 - PloverPackagePrivate *priv;
18.123 - const char *license=NULL;
18.124 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.125 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.126 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_LICENSE,&license,
18.127 - RAZOR_DETAIL_LAST);
18.128 - return license;
18.129 -}
18.130 -
18.131 -const char *plover_package_get_arch(PloverPackage *package)
18.132 -{
18.133 - PloverPackagePrivate *priv;
18.134 - const char *arch=NULL;
18.135 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.136 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.137 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_ARCH,&arch,
18.138 - RAZOR_DETAIL_LAST);
18.139 - return arch;
18.140 -}
18.141 -
18.142 -const char *plover_package_get_description(PloverPackage *package)
18.143 -{
18.144 - PloverPackagePrivate *priv;
18.145 - const char *description=NULL;
18.146 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.147 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.148 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_DESCRIPTION,
18.149 - &description,RAZOR_DETAIL_LAST);
18.150 - return description;
18.151 -}
18.152 -
18.153 -const char *plover_package_get_URL(PloverPackage *package)
18.154 -{
18.155 - PloverPackagePrivate *priv;
18.156 - const char *URL=NULL;
18.157 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.158 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.159 - razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_URL,&URL,
18.160 - RAZOR_DETAIL_LAST);
18.161 - return URL;
18.162 -}
18.163 -
18.164 -GdkPixbuf *plover_package_get_icon(PloverPackage *package)
18.165 -{
18.166 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.167 - return NULL;
18.168 -}
18.169 -
18.170 -PloverPackageFileStore *plover_package_get_file_store(PloverPackage *package)
18.171 -{
18.172 - PloverPackagePrivate *priv;
18.173 - struct razor_file_iterator *iter;
18.174 - g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
18.175 - priv=PLOVER_PACKAGE_GET_PRIVATE(package);
18.176 - if (!priv->file_store)
18.177 - {
18.178 - iter=razor_file_iterator_create(priv->set,priv->pkg,0);
18.179 - priv->file_store=plover_package_file_store_new(iter);
18.180 - razor_file_iterator_destroy(iter);
18.181 - }
18.182 - return priv->file_store;
18.183 -}
19.1 --- a/plover-gtk/package.h Fri Mar 23 20:29:50 2012 +0000
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,50 +0,0 @@
19.4 -#ifndef __PLOVER_PACKAGE_H__
19.5 -#define __PLOVER_PACKAGE_H__
19.6 -
19.7 -#include <razor.h>
19.8 -#include <glib-object.h>
19.9 -#include <gdk-pixbuf/gdk-pixbuf.h>
19.10 -#include <plover-gtk/packageset.h>
19.11 -#include <plover-gtk/packagefilestore.h>
19.12 -
19.13 -G_BEGIN_DECLS
19.14 -
19.15 -#define PLOVER_TYPE_PACKAGE plover_package_get_type()
19.16 -#define PLOVER_PACKAGE(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
19.17 - PLOVER_TYPE_PACKAGE,PloverPackage)
19.18 -#define PLOVER_PACKAGE_CLASS(klass)\
19.19 - G_TYPE_CHECK_CLASS_CAST(klass,\
19.20 - PLOVER_TYPE_PACKAGE,PloverPackageClass)
19.21 -#define PLOVER_IS_PACKAGE(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj,\
19.22 - PLOVER_TYPE_PACKAGE)
19.23 -#define PLOVER_IS_PACKAGE_CLASS(klass)\
19.24 - G_TYPE_CHECK_CLASS_TYPE(obj,\
19.25 - PLOVER_TYPE_PACKAGE)
19.26 -#define PLOVER_PACKAGE_GET_CLASS(obj)\
19.27 - G_TYPE_INSTANCE_GET_CLASS(obj,\
19.28 - PLOVER_TYPE_PACKAGE,PloverPackageClass)
19.29 -
19.30 -typedef struct _PloverPackage {
19.31 - GObject parent_instance;
19.32 -} PloverPackage;
19.33 -
19.34 -typedef struct _PloverPackageClass {
19.35 - GObjectClass parent_class;
19.36 -} PloverPackageClass;
19.37 -
19.38 -GType plover_package_get_type(void) G_GNUC_CONST;
19.39 -PloverPackage *plover_package_new(struct razor_set *set,
19.40 - struct razor_package *pkg);
19.41 -const char *plover_package_get_name(PloverPackage *package);
19.42 -const char *plover_package_get_summary(PloverPackage *package);
19.43 -const char *plover_package_get_version(PloverPackage *package);
19.44 -const char *plover_package_get_license(PloverPackage *package);
19.45 -const char *plover_package_get_arch(PloverPackage *package);
19.46 -const char *plover_package_get_description(PloverPackage *package);
19.47 -const char *plover_package_get_URL(PloverPackage *package);
19.48 -GdkPixbuf *plover_package_get_icon(PloverPackage *package);
19.49 -PloverPackageFileStore *plover_package_get_file_store(PloverPackage *package);
19.50 -
19.51 -G_END_DECLS
19.52 -
19.53 -#endif /* __PLOVER_PACKAGE_H__ */
20.1 --- a/plover-gtk/packagefilestore.c Fri Mar 23 20:29:50 2012 +0000
20.2 +++ b/plover-gtk/packagefilestore.c Sat Nov 15 19:04:45 2014 +0000
20.3 @@ -257,3 +257,15 @@
20.4 gtk_tree_path_free(path);
20.5 return store;
20.6 }
20.7 +
20.8 +PloverPackageFileStore *
20.9 + plover_package_file_store_new_from_package(PloverPackage *package)
20.10 +{
20.11 + PloverPackageFileStore *store;
20.12 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
20.13 + struct razor_file_iterator *iter;
20.14 + iter=plover_package_file_iterator_create(package,FALSE);
20.15 + store=GTK_TREE_MODEL(plover_package_file_store_new(iter));
20.16 + razor_file_iterator_destroy(iter);
20.17 + return store;
20.18 +}
21.1 --- a/plover-gtk/packagefilestore.h Fri Mar 23 20:29:50 2012 +0000
21.2 +++ b/plover-gtk/packagefilestore.h Sat Nov 15 19:04:45 2014 +0000
21.3 @@ -2,6 +2,7 @@
21.4 #define __PLOVER_PACKAGE_FILE_STORE_H__
21.5
21.6 #include <glib-object.h>
21.7 +#include <plover/package.h>
21.8 #include <razor.h>
21.9
21.10 G_BEGIN_DECLS
21.11 @@ -44,6 +45,8 @@
21.12 GType plover_package_file_store_get_type(void) G_GNUC_CONST;
21.13 PloverPackageFileStore *
21.14 plover_package_file_store_new(struct razor_file_iterator *files);
21.15 +PloverPackageFileStore *
21.16 + plover_package_file_store_new_from_package(PloverPackage *package);
21.17
21.18 G_END_DECLS
21.19
22.1 --- a/plover-gtk/packageset.c Fri Mar 23 20:29:50 2012 +0000
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,259 +0,0 @@
22.4 -/*
22.5 - * Copyright (C) 2010-2012 J. Ali Harlow <ali@juiblex.co.uk>
22.6 - *
22.7 - * This program is free software; you can redistribute it and/or modify
22.8 - * it under the terms of the GNU General Public License as published by
22.9 - * the Free Software Foundation; either version 2 of the License, or
22.10 - * (at your option) any later version.
22.11 - *
22.12 - * This program is distributed in the hope that it will be useful,
22.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.15 - * GNU General Public License for more details.
22.16 - *
22.17 - * You should have received a copy of the GNU General Public License along
22.18 - * with this program; if not, write to the Free Software Foundation, Inc.,
22.19 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22.20 - */
22.21 -
22.22 -#include "config.h"
22.23 -#include <stdlib.h>
22.24 -#include <string.h>
22.25 -#include <fcntl.h>
22.26 -#include <errno.h>
22.27 -#include <unistd.h>
22.28 -#include <glib-object.h>
22.29 -#include <razor.h>
22.30 -#include "plover/plover.h"
22.31 -#include "plover-gtk/error.h"
22.32 -#include "plover-gtk/packageset.h"
22.33 -#include "plover-gtk/package.h"
22.34 -
22.35 -G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT);
22.36 -
22.37 -typedef struct _PloverPackageSetPrivate {
22.38 - struct razor_root *root;
22.39 - struct razor_set *set;
22.40 - GSList *packages;
22.41 - int no_details;
22.42 -} PloverPackageSetPrivate;
22.43 -
22.44 -#define PLOVER_PACKAGE_SET_GET_PRIVATE(obj)\
22.45 - G_TYPE_INSTANCE_GET_PRIVATE(obj,\
22.46 - PLOVER_TYPE_PACKAGE_SET,\
22.47 - PloverPackageSetPrivate)
22.48 -
22.49 -enum {
22.50 - CHANGED=0,
22.51 - N_SIGNALS
22.52 -};
22.53 -
22.54 -static guint signals[N_SIGNALS];
22.55 -
22.56 -static void plover_package_set_finalize(GObject *obj)
22.57 -{
22.58 - PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
22.59 - if (priv->root)
22.60 - razor_root_close(priv->root);
22.61 - if (G_OBJECT_CLASS(plover_package_set_parent_class)->finalize)
22.62 - G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj);
22.63 -}
22.64 -
22.65 -static void plover_package_set_dispose(GObject *obj)
22.66 -{
22.67 - PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
22.68 - if (priv->set)
22.69 - {
22.70 - razor_set_unref(priv->set);
22.71 - priv->set=NULL;
22.72 - }
22.73 - if (G_OBJECT_CLASS(plover_package_set_parent_class)->dispose)
22.74 - G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj);
22.75 -}
22.76 -
22.77 -static void plover_package_set_class_init(PloverPackageSetClass *klass)
22.78 -{
22.79 - GObjectClass *oclass=G_OBJECT_CLASS(klass);
22.80 - oclass->finalize=plover_package_set_finalize;
22.81 - oclass->dispose=plover_package_set_dispose;
22.82 - g_type_class_add_private(klass,sizeof(PloverPackageSetPrivate));
22.83 - signals[CHANGED]=g_signal_newv("changed",
22.84 - G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
22.85 - g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
22.86 -}
22.87 -
22.88 -static void plover_package_set_init(PloverPackageSet *set)
22.89 -{
22.90 - PloverPackageSetPrivate *priv;
22.91 - priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
22.92 - priv->no_details=-1;
22.93 -}
22.94 -
22.95 -PloverPackageSet *plover_package_set_new(void)
22.96 -{
22.97 - return g_object_new(PLOVER_TYPE_PACKAGE_SET,NULL);
22.98 -}
22.99 -
22.100 -PloverPackageSet *plover_package_set_new_from_installed(const char *root,
22.101 - GError **err)
22.102 -{
22.103 - PloverPackageSet *set;
22.104 - PloverPackageSetPrivate *priv;
22.105 - struct razor_error *error=NULL;
22.106 - set=plover_package_set_new();
22.107 - priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
22.108 - priv->root=razor_root_open(root,&error);
22.109 - if (!priv->root)
22.110 - {
22.111 - g_set_error_literal(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
22.112 - razor_error_get_msg(error));
22.113 - razor_error_free(error);
22.114 - g_object_unref(set);
22.115 - return NULL;
22.116 - }
22.117 - priv->set=razor_set_ref(razor_root_get_system_set(priv->root));
22.118 - if (!priv->set)
22.119 - {
22.120 - g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
22.121 - "Failed to get system set from %s",root);
22.122 - g_object_unref(set);
22.123 - return NULL;
22.124 - }
22.125 - return set;
22.126 -}
22.127 -
22.128 -PloverPackageSet *plover_package_set_new_from_repository(const char *base,
22.129 - struct razor_relocations *relocations,GError **err)
22.130 -{
22.131 -#if HAVE_FCHDIR
22.132 - int fd;
22.133 -#else
22.134 - size_t wd_len;
22.135 - char *wd;
22.136 -#endif
22.137 - gchar *s;
22.138 - struct razor_set *reloc;
22.139 - struct razor_error *error=NULL;
22.140 - PloverPackageSet *set;
22.141 - PloverPackageSetPrivate *priv;
22.142 - set=plover_package_set_new();
22.143 - priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
22.144 -#if HAVE_FCHDIR
22.145 - fd=open(".",O_RDONLY);
22.146 -#else
22.147 - wd_len=32;
22.148 - wd=malloc(wd_len);
22.149 - while (!getcwd(wd,wd_len) && errno==ERANGE)
22.150 - {
22.151 - free(wd);
22.152 - wd_len*=2;
22.153 - wd=malloc(wd_len);
22.154 - }
22.155 -#endif
22.156 - s=g_build_filename(base,"repodata",NULL);
22.157 - if (chdir(s)<0)
22.158 - {
22.159 - g_set_error(err,G_FILE_ERROR,g_file_error_from_errno(errno),
22.160 - "%s: %s",s,g_strerror(errno));
22.161 - g_object_unref(set);
22.162 -#if HAVE_FCHDIR
22.163 - close(fd);
22.164 -#else
22.165 - free(wd);
22.166 -#endif
22.167 - return NULL;
22.168 - }
22.169 - g_free(s);
22.170 - priv->set=plover_razor_set_create_from_yum("..");
22.171 -#if HAVE_FCHDIR
22.172 - (void)fchdir(fd);
22.173 - close(fd);
22.174 -#else
22.175 - chdir(wd);
22.176 - free(wd);
22.177 -#endif
22.178 - if (priv->set && relocations)
22.179 - {
22.180 - reloc=plover_relocate_packages(priv->set,base,relocations,&error);
22.181 - if (!reloc)
22.182 - {
22.183 - g_set_error_literal(err,PLOVER_RAZOR_ERROR,
22.184 - PLOVER_RAZOR_ERROR_FAILED,razor_error_get_msg(error));
22.185 - razor_error_free(error);
22.186 - g_object_unref(set);
22.187 - return NULL;
22.188 - }
22.189 - razor_set_unref(priv->set);
22.190 - priv->set=reloc;
22.191 - }
22.192 - if (!priv->set)
22.193 - {
22.194 - g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
22.195 - "Failed to create package set from repository %s",base);
22.196 - g_object_unref(set);
22.197 - return NULL;
22.198 - }
22.199 - return set;
22.200 -}
22.201 -
22.202 -GSList *plover_package_set_get_packages(PloverPackageSet *set)
22.203 -{
22.204 - struct razor_package_iterator *iter;
22.205 - struct razor_package *pkg;
22.206 - PloverPackageSetPrivate *priv;
22.207 - PloverPackage *package;
22.208 - g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
22.209 - priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
22.210 - if (priv->set && !priv->packages)
22.211 - {
22.212 - iter=razor_package_iterator_create(priv->set);
22.213 - while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_LAST))
22.214 - {
22.215 - package=plover_package_new(priv->set,pkg);
22.216 - priv->packages=g_slist_prepend(priv->packages,package);
22.217 - }
22.218 - razor_package_iterator_destroy(iter);
22.219 - }
22.220 - return priv->packages;
22.221 -}
22.222 -
22.223 -/*
22.224 - * Some versions of razor have a bug which causes all detail strings
22.225 - * to be discarded. If such a version of razor is used to install or
22.226 - * update a package, then all the detail strings for the installed
22.227 - * set will be lost. This function tests for this condition and can
22.228 - * be used to present something more useful than blank details.
22.229 - */
22.230 -
22.231 -gboolean plover_package_set_get_no_details(PloverPackageSet *set)
22.232 -{
22.233 - PloverPackageSetPrivate *priv;
22.234 - PloverPackage *package;
22.235 - GSList *packages,*link;
22.236 - g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
22.237 - priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
22.238 - if (priv->no_details<0)
22.239 - {
22.240 - packages=plover_package_set_get_packages(set);
22.241 - if (packages)
22.242 - {
22.243 - priv->no_details=0;
22.244 - for(link=packages;link;link=link->next)
22.245 - {
22.246 - package=link->data;
22.247 - priv->no_details+=2;
22.248 - if (*plover_package_get_summary(package))
22.249 - priv->no_details--;
22.250 - if (*plover_package_get_license(package))
22.251 - priv->no_details--;
22.252 - if (*plover_package_get_description(package))
22.253 - priv->no_details--;
22.254 - if (*plover_package_get_URL(package))
22.255 - priv->no_details--;
22.256 - }
22.257 - if (priv->no_details<0) /* More than 50% of strings present */
22.258 - priv->no_details=0;
22.259 - }
22.260 - }
22.261 - return priv->no_details>0;
22.262 -}
23.1 --- a/plover-gtk/packageset.h Fri Mar 23 20:29:50 2012 +0000
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,46 +0,0 @@
23.4 -#ifndef __PLOVER_PACKAGE_SET_H__
23.5 -#define __PLOVER_PACKAGE_SET_H__
23.6 -
23.7 -#include <razor.h>
23.8 -#include <glib-object.h>
23.9 -
23.10 -G_BEGIN_DECLS
23.11 -
23.12 -#define PLOVER_TYPE_PACKAGE_SET plover_package_set_get_type()
23.13 -#define PLOVER_PACKAGE_SET(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
23.14 - PLOVER_TYPE_PACKAGE_SET,PloverPackageSet)
23.15 -#define PLOVER_PACKAGE_SET_CLASS(klass)\
23.16 - G_TYPE_CHECK_CLASS_CAST(klass,\
23.17 - PLOVER_TYPE_PACKAGE_SET,\
23.18 - PloverPackageSetClass)
23.19 -#define PLOVER_IS_PACKAGE_SET(obj)\
23.20 - G_TYPE_CHECK_INSTANCE_TYPE(obj,\
23.21 - PLOVER_TYPE_PACKAGE_SET)
23.22 -#define PLOVER_IS_PACKAGE_SET_CLASS(klass)\
23.23 - G_TYPE_CHECK_CLASS_TYPE(obj,\
23.24 - PLOVER_TYPE_PACKAGE_SET)
23.25 -#define PLOVER_PACKAGE_SET_GET_CLASS(obj)\
23.26 - G_TYPE_INSTANCE_GET_CLASS(obj,\
23.27 - PLOVER_TYPE_PACKAGE_SET,\
23.28 - PloverPackageSetClass)
23.29 -
23.30 -typedef struct _PloverPackageSet {
23.31 - GObject parent_instance;
23.32 -} PloverPackageSet;
23.33 -
23.34 -typedef struct _PloverPackageSetClass {
23.35 - GObjectClass parent_class;
23.36 -} PloverPackageSetClass;
23.37 -
23.38 -GType plover_package_set_get_type(void) G_GNUC_CONST;
23.39 -PloverPackageSet *plover_package_set_new(void);
23.40 -PloverPackageSet *plover_package_set_new_from_installed(const char *root,
23.41 - GError **err);
23.42 -PloverPackageSet *plover_package_set_new_from_repository(const char *base,
23.43 - struct razor_relocations *relocations,GError **err);
23.44 -GSList *plover_package_set_get_packages(PloverPackageSet *set);
23.45 -gboolean plover_package_set_get_no_details(PloverPackageSet *set);
23.46 -
23.47 -G_END_DECLS
23.48 -
23.49 -#endif /* __PLOVER_PACKAGE_SET_H__ */
24.1 --- a/plover-gtk/packagestore.c Fri Mar 23 20:29:50 2012 +0000
24.2 +++ b/plover-gtk/packagestore.c Sat Nov 15 19:04:45 2014 +0000
24.3 @@ -24,7 +24,7 @@
24.4 #include <gtk/gtk.h>
24.5 #include <razor.h>
24.6 #include "plover/plover.h"
24.7 -#include "plover-gtk/package.h"
24.8 +#include "plover/package.h"
24.9 #include "plover-gtk/packagestore.h"
24.10
24.11 #define VALID_ITER(iter,store) ((iter) && (iter)->user_data && \
24.12 @@ -139,6 +139,8 @@
24.13 char *s;
24.14 PloverPackageStore *store=(PloverPackageStore *)tree_model;
24.15 PloverPackage *package;
24.16 + GInputStream *stream;
24.17 + GdkPixbuf *icon;
24.18 g_return_if_fail(column>=0 && column<PLOVER_PACKAGE_STORE_NO_COLUMNS);
24.19 g_return_if_fail(VALID_ITER(iter,store));
24.20 package=PLOVER_PACKAGE(g_sequence_get(iter->user_data));
24.21 @@ -151,7 +153,15 @@
24.22 case PLOVER_PACKAGE_STORE_INSTALLED_COLUMN:
24.23 break;
24.24 case PLOVER_PACKAGE_STORE_ICON_COLUMN:
24.25 - g_value_set_object(value,plover_package_get_icon(package));
24.26 + stream=plover_package_read_icon(package,NULL);
24.27 + if (stream)
24.28 + {
24.29 + icon=gdk_pixbuf_new_from_stream(stream,NULL,NULL);
24.30 + g_object_unref(stream);
24.31 + }
24.32 + else
24.33 + icon=NULL;
24.34 + g_value_set_object(value,icon);
24.35 break;
24.36 case PLOVER_PACKAGE_STORE_NAME_COLUMN:
24.37 g_value_set_string(value,plover_package_get_name(package));
25.1 --- a/plover-gtk/packagestore.h Fri Mar 23 20:29:50 2012 +0000
25.2 +++ b/plover-gtk/packagestore.h Sat Nov 15 19:04:45 2014 +0000
25.3 @@ -2,7 +2,7 @@
25.4 #define __PLOVER_PACKAGE_STORE_H__
25.5
25.6 #include <glib-object.h>
25.7 -#include <plover-gtk/packageset.h>
25.8 +#include <plover/packageset.h>
25.9
25.10 G_BEGIN_DECLS
25.11
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/plover-gtk/software-installation.ui Sat Nov 15 19:04:45 2014 +0000
26.3 @@ -0,0 +1,175 @@
26.4 +<?xml version="1.0"?>
26.5 +<interface>
26.6 + <requires lib="gtk+" version="2.16"/>
26.7 + <!-- interface-naming-policy project-wide -->
26.8 + <object class="GtkAssistant" id="SoftwareInstallation">
26.9 + <property name="border_width">12</property>
26.10 + <property name="title" translatable="yes">Software Installation</property>
26.11 + <signal name="delete_event" handler="gtk_main_quit"/>
26.12 + <child>
26.13 + <placeholder/>
26.14 + </child>
26.15 + <child>
26.16 + <placeholder/>
26.17 + </child>
26.18 + <child>
26.19 + <object class="GtkLabel" id="SIIntroduction">
26.20 + <property name="visible">True</property>
26.21 + <property name="xalign">0</property>
26.22 + <property name="yalign">0</property>
26.23 + <property name="xpad">16</property>
26.24 + <property name="ypad">16</property>
26.25 + <property name="label" translatable="yes"><b>Welcome to the Installation Assistant</b>
26.26 +
26.27 +The Installation Assistant will install the software.
26.28 +To continue, click Forward.</property>
26.29 + <property name="use_markup">True</property>
26.30 + </object>
26.31 + <packing>
26.32 + <property name="page_type">intro</property>
26.33 + <property name="title" translatable="yes">Software Installation</property>
26.34 + </packing>
26.35 + </child>
26.36 + <child>
26.37 + <object class="GtkVBox" id="SIConfirm">
26.38 + <property name="visible">True</property>
26.39 + <property name="orientation">vertical</property>
26.40 + <child>
26.41 + <object class="GtkVBox" id="SIIncompatibleInstallation">
26.42 + <property name="orientation">vertical</property>
26.43 + <child>
26.44 + <object class="GtkLabel" id="SIIncompatibleInstallationLabel">
26.45 + <property name="visible">True</property>
26.46 + <property name="xalign">0</property>
26.47 + <property name="yalign">0</property>
26.48 + <property name="xpad">16</property>
26.49 + <property name="ypad">16</property>
26.50 + <property name="label" translatable="yes"><b>Incompatible Installation</b>
26.51 +
26.52 +The existing installation is not from %s
26.53 +In order to continue, all the existing packages must be removed.</property>
26.54 + <property name="use_markup">True</property>
26.55 + </object>
26.56 + <packing>
26.57 + <property name="expand">False</property>
26.58 + <property name="position">0</property>
26.59 + </packing>
26.60 + </child>
26.61 + <child>
26.62 + <object class="GtkAlignment" id="alignment4">
26.63 + <property name="visible">True</property>
26.64 + <property name="left_padding">16</property>
26.65 + <property name="right_padding">16</property>
26.66 + <child>
26.67 + <object class="GtkCheckButton" id="SIRemoveExisting">
26.68 + <property name="label" translatable="yes">Remove all existing packages</property>
26.69 + <property name="visible">True</property>
26.70 + <property name="can_focus">True</property>
26.71 + <property name="receives_default">False</property>
26.72 + <property name="draw_indicator">True</property>
26.73 + </object>
26.74 + </child>
26.75 + </object>
26.76 + <packing>
26.77 + <property name="expand">False</property>
26.78 + <property name="position">1</property>
26.79 + </packing>
26.80 + </child>
26.81 + </object>
26.82 + <packing>
26.83 + <property name="expand">False</property>
26.84 + <property name="position">0</property>
26.85 + </packing>
26.86 + </child>
26.87 + <child>
26.88 + <object class="GtkLabel" id="SISummaryOfWork">
26.89 + <property name="width_request">450</property>
26.90 + <property name="visible">True</property>
26.91 + <property name="xalign">0</property>
26.92 + <property name="yalign">0</property>
26.93 + <property name="xpad">16</property>
26.94 + <property name="ypad">16</property>
26.95 + <property name="label" translatable="yes"><b>Installation Summary</b>
26.96 +
26.97 +Packages to be installed or updated: ... plus dependencies.</property>
26.98 + <property name="use_markup">True</property>
26.99 + <property name="wrap">True</property>
26.100 + </object>
26.101 + <packing>
26.102 + <property name="position">1</property>
26.103 + </packing>
26.104 + </child>
26.105 + </object>
26.106 + <packing>
26.107 + <property name="page_type">confirm</property>
26.108 + <property name="title" translatable="yes">Software Installation (2 of 4)</property>
26.109 + </packing>
26.110 + </child>
26.111 + <child>
26.112 + <object class="GtkVBox" id="SIProgress">
26.113 + <property name="visible">True</property>
26.114 + <property name="orientation">vertical</property>
26.115 + <child>
26.116 + <object class="GtkLabel" id="label1">
26.117 + <property name="visible">True</property>
26.118 + <property name="xalign">0</property>
26.119 + <property name="yalign">0</property>
26.120 + <property name="xpad">16</property>
26.121 + <property name="ypad">16</property>
26.122 + <property name="label" translatable="yes"><b>Installing the Software</b>
26.123 +
26.124 +Please wait while the Installation Assistant installs the software.
26.125 +This may take several minutes.</property>
26.126 + <property name="use_markup">True</property>
26.127 + </object>
26.128 + <packing>
26.129 + <property name="expand">False</property>
26.130 + <property name="position">0</property>
26.131 + </packing>
26.132 + </child>
26.133 + <child>
26.134 + <object class="GtkAlignment" id="alignment2">
26.135 + <property name="visible">True</property>
26.136 + <property name="bottom_padding">16</property>
26.137 + <property name="left_padding">16</property>
26.138 + <property name="right_padding">16</property>
26.139 + <child>
26.140 + <object class="GtkProgressBar" id="SIProgressBar">
26.141 + <property name="visible">True</property>
26.142 + <property name="activity_mode">True</property>
26.143 + <property name="show_text">True</property>
26.144 + <property name="text" translatable="yes">Unpacking files</property>
26.145 + </object>
26.146 + </child>
26.147 + </object>
26.148 + <packing>
26.149 + <property name="expand">False</property>
26.150 + <property name="position">1</property>
26.151 + </packing>
26.152 + </child>
26.153 + </object>
26.154 + <packing>
26.155 + <property name="page_type">progress</property>
26.156 + <property name="title" translatable="yes">Software Installation (3 of 4)</property>
26.157 + </packing>
26.158 + </child>
26.159 + <child>
26.160 + <object class="GtkLabel" id="SISummary">
26.161 + <property name="visible">True</property>
26.162 + <property name="xalign">0</property>
26.163 + <property name="yalign">0</property>
26.164 + <property name="xpad">16</property>
26.165 + <property name="ypad">16</property>
26.166 + <property name="label" translatable="yes"><b>Installation Assistant Completed</b>
26.167 +
26.168 +The Installation Assistant has successfully completed.
26.169 +Click Close to exit the Assistant.</property>
26.170 + <property name="use_markup">True</property>
26.171 + </object>
26.172 + <packing>
26.173 + <property name="page_type">summary</property>
26.174 + <property name="title" translatable="yes">Software Installation (4 of 4)</property>
26.175 + </packing>
26.176 + </child>
26.177 + </object>
26.178 +</interface>
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/plover-gtk/stockicons.c Sat Nov 15 19:04:45 2014 +0000
27.3 @@ -0,0 +1,141 @@
27.4 +/*
27.5 + * Copyright (C) 2010 J. Ali Harlow <ali@juiblex.co.uk>
27.6 + *
27.7 + * This program is free software; you can redistribute it and/or modify
27.8 + * it under the terms of the GNU General Public License as published by
27.9 + * the Free Software Foundation; either version 2 of the License, or
27.10 + * (at your option) any later version.
27.11 + *
27.12 + * This program is distributed in the hope that it will be useful,
27.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.15 + * GNU General Public License for more details.
27.16 + *
27.17 + * You should have received a copy of the GNU General Public License along
27.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
27.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27.20 + */
27.21 +
27.22 +#include "config.h"
27.23 +#include <stdlib.h>
27.24 +#ifdef WIN32
27.25 +#include <windows.h>
27.26 +#endif /* WIN32 */
27.27 +#include <glib.h>
27.28 +#include <gtk/gtk.h>
27.29 +#include <plover-gtk/stockicons.h>
27.30 +
27.31 +/* Checks whether a loader for SVG files has been registered
27.32 + * with GdkPixbuf.
27.33 + */
27.34 +static gboolean plover_pixbuf_supports_svg(void)
27.35 +{
27.36 + GSList *formats;
27.37 + GSList *tmp_list;
27.38 + static gint found_svg=-1;
27.39 + gchar **mime_types,**mime_type;
27.40 + if (found_svg!=-1)
27.41 + return found_svg;
27.42 + formats=gdk_pixbuf_get_formats();
27.43 + found_svg=FALSE;
27.44 + for (tmp_list=formats;tmp_list && !found_svg;tmp_list=tmp_list->next)
27.45 + {
27.46 + mime_types=gdk_pixbuf_format_get_mime_types(tmp_list->data);
27.47 + for (mime_type=mime_types;*mime_type && !found_svg;mime_type++)
27.48 + if (!strcmp(*mime_type,"image/svg"))
27.49 + found_svg=TRUE;
27.50 + g_strfreev(mime_types);
27.51 + }
27.52 + g_slist_free(formats);
27.53 + return found_svg;
27.54 +}
27.55 +
27.56 +static void plover_install_icon_at_size(const char *icon_name,
27.57 + GtkIconSet *icon_set,GtkIconSize size,const char *filename)
27.58 +{
27.59 + int w,h;
27.60 + GdkPixbuf *pixbuf;
27.61 + GtkIconSource *source;
27.62 + if (gtk_icon_size_lookup(size,&w,&h))
27.63 + {
27.64 + pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,NULL);
27.65 + if (pixbuf)
27.66 + {
27.67 + source=gtk_icon_source_new();
27.68 + gtk_icon_source_set_size_wildcarded(source,FALSE);
27.69 + gtk_icon_source_set_size(source,size);
27.70 + gtk_icon_source_set_pixbuf(source,pixbuf);
27.71 + gtk_icon_set_add_source(icon_set,source);
27.72 + gtk_icon_source_free(source);
27.73 + g_object_unref(pixbuf);
27.74 + }
27.75 + }
27.76 +}
27.77 +
27.78 +/**
27.79 + * plover_icons_add_to_stock:
27.80 + * @type: The icon type, typically "apps" or "mimetype"
27.81 + * @name: The icon name (the basename of files containing the icons)
27.82 + *
27.83 + * Find icons in <datadir>/icons/hicolor and add them to the stock images
27.84 + * so that, for example, gtk_image_new_from_stock() will be able find them.
27.85 + *
27.86 + * If there is an SVG loader registered with GdkPixbuf, then:
27.87 + * <datadir>/icons/hicolor/scalable/@type/@name.svg will be used. Otherwise,
27.88 + * <datadir>/icons/hicolor/24x24/@type/@name.png and
27.89 + * <datadir>/icons/hicolor/48x48/@type/@name.png will be used.
27.90 + */
27.91 +void plover_icons_add_to_stock(const char *type,const char *name)
27.92 +{
27.93 + gchar *prefix,*s,*filename;
27.94 + GtkIconSource *source;
27.95 + GtkIconSet *icon_set;
27.96 + GtkIconFactory *factory;
27.97 + factory=gtk_icon_factory_new();
27.98 + icon_set=gtk_icon_set_new();
27.99 +#ifdef WIN32
27.100 + prefix=g_win32_get_package_installation_directory_of_module(NULL);
27.101 +#else
27.102 + prefix=NULL;
27.103 +#endif
27.104 + if (plover_pixbuf_supports_svg())
27.105 + {
27.106 + source=gtk_icon_source_new();
27.107 + s=g_strconcat(name,".svg");
27.108 + filename=g_build_filename(prefix?prefix:"/usr",
27.109 + "share/icons/hicolor/scalable",type,s,NULL);
27.110 + g_free(s);
27.111 + gtk_icon_source_set_filename(source,filename);
27.112 + g_free(filename);
27.113 + gtk_icon_set_add_source(icon_set,source);
27.114 + gtk_icon_source_free(source);
27.115 + }
27.116 + else
27.117 + {
27.118 + s=g_strconcat(name,".png");
27.119 + filename=g_build_filename(prefix?prefix:"/usr",
27.120 + "share/icons/hicolor/24x24",type,s,NULL);
27.121 + plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_MENU,
27.122 + filename);
27.123 + plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_BUTTON,
27.124 + filename);
27.125 + plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_SMALL_TOOLBAR,
27.126 + filename);
27.127 + plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_LARGE_TOOLBAR,
27.128 + filename);
27.129 + g_free(filename);
27.130 + filename=g_build_filename(prefix?prefix:"/usr",
27.131 + "share/icons/hicolor/48x48",type,s,NULL);
27.132 + plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_DND,
27.133 + filename);
27.134 + plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_DIALOG,
27.135 + filename);
27.136 + g_free(filename);
27.137 + g_free(s);
27.138 + }
27.139 + gtk_icon_factory_add(factory,name,icon_set);
27.140 + gtk_icon_set_unref(icon_set);
27.141 + //icon_set=gtk_icon_factory_lookup(factory,name);
27.142 + gtk_icon_factory_add_default(factory);
27.143 + g_object_unref(factory);
27.144 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/plover-gtk/stockicons.h Sat Nov 15 19:04:45 2014 +0000
28.3 @@ -0,0 +1,6 @@
28.4 +#ifndef __PLOVER_STOCK_ICONS_H__
28.5 +#define __PLOVER_STOCK_ICONS_H__
28.6 +
28.7 +void plover_icons_add_to_stock(const char *type,const char *name);
28.8 +
28.9 +#endif /* __PLOVER_STOCK_ICONS_H__ */
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/plover-gtk/transactionhelper.c Sat Nov 15 19:04:45 2014 +0000
29.3 @@ -0,0 +1,1037 @@
29.4 +/*
29.5 + * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
29.6 + *
29.7 + * This program is free software; you can redistribute it and/or modify
29.8 + * it under the terms of the GNU General Public License as published by
29.9 + * the Free Software Foundation; either version 2 of the License, or
29.10 + * (at your option) any later version.
29.11 + *
29.12 + * This program is distributed in the hope that it will be useful,
29.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29.15 + * GNU General Public License for more details.
29.16 + *
29.17 + * You should have received a copy of the GNU General Public License along
29.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
29.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29.20 + */
29.21 +
29.22 +#include "config.h"
29.23 +#include <stdlib.h>
29.24 +#include <errno.h>
29.25 +#include <gtk/gtk.h>
29.26 +#include <plover/plover.h>
29.27 +#include <plover/transaction.h>
29.28 +#include <plover-gtk/transactionhelper.h>
29.29 +
29.30 +/*
29.31 + * A PloverTransactionHelper uses a GtkAssistant to help a user run a
29.32 + * transaction.
29.33 + */
29.34 +
29.35 +G_DEFINE_TYPE(PloverTransactionHelper,plover_transaction_helper,G_TYPE_OBJECT)
29.36 +
29.37 +enum {
29.38 + CLOSE=0,
29.39 + N_SIGNALS
29.40 +};
29.41 +
29.42 +static guint signals[N_SIGNALS];
29.43 +
29.44 +static void plover_transaction_helper_finalize(PloverTransactionHelper *helper)
29.45 +{
29.46 + g_free(helper->error_primary_text);
29.47 + g_free(helper->base);
29.48 + g_free(helper->unsatisfied);
29.49 + if (helper->comps)
29.50 + plover_comps_free(helper->comps);
29.51 + plover_vector_free(helper->report_adding);
29.52 + plover_vector_free(helper->report_removing);
29.53 +}
29.54 +
29.55 +static void plover_transaction_helper_dispose(PloverTransactionHelper *helper)
29.56 +{
29.57 + g_clear_error(&helper->error);
29.58 + if (helper->error_dialog)
29.59 + {
29.60 + g_signal_handlers_disconnect_by_data(helper->error_dialog,helper);
29.61 + gtk_widget_destroy(helper->error_dialog);
29.62 + helper->error_dialog=NULL;
29.63 + }
29.64 + if (helper->assistant)
29.65 + {
29.66 + g_signal_handlers_disconnect_by_data(helper->assistant,helper);
29.67 + g_clear_object(&helper->assistant);
29.68 + }
29.69 + g_clear_object(&helper->ui);
29.70 + g_slist_foreach(helper->transactions,(GFunc)g_object_unref,NULL);
29.71 + g_slist_free(helper->transactions);
29.72 + helper->transactions=NULL;
29.73 + g_clear_object(&helper->installed);
29.74 + g_clear_object(&helper->upstream);
29.75 + g_clear_object(&helper->relocated_upstream);
29.76 +}
29.77 +
29.78 +static void
29.79 + plover_transaction_helper_class_init(PloverTransactionHelperClass *klass)
29.80 +{
29.81 + GObjectClass *gobject_class=G_OBJECT_CLASS(klass);
29.82 + gobject_class->finalize=
29.83 + (void (*)(GObject *))plover_transaction_helper_finalize;
29.84 + gobject_class->dispose=
29.85 + (void (*)(GObject *))plover_transaction_helper_dispose;
29.86 + signals[CLOSE]=g_signal_newv("close",
29.87 + G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
29.88 + g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
29.89 +}
29.90 +
29.91 +static void plover_transaction_helper_init(PloverTransactionHelper *helper)
29.92 +{
29.93 + helper->report_adding=plover_vector_new();
29.94 + helper->report_removing=plover_vector_new();
29.95 +}
29.96 +
29.97 +static void plover_transaction_helper_assistant_cancel(GtkAssistant *assistant,
29.98 + PloverTransactionHelper *helper)
29.99 +{
29.100 + gtk_widget_hide(GTK_WIDGET(helper->assistant));
29.101 + gtk_assistant_set_current_page(helper->assistant,0);
29.102 + g_signal_emit(helper,signals[CLOSE],0);
29.103 +}
29.104 +
29.105 +static void plover_transaction_helper_assistant_close(GtkAssistant *assistant,
29.106 + PloverTransactionHelper *helper)
29.107 +{
29.108 + gtk_widget_hide(GTK_WIDGET(helper->assistant));
29.109 + gtk_assistant_set_current_page(helper->assistant,0);
29.110 + g_signal_emit(helper,signals[CLOSE],0);
29.111 +}
29.112 +
29.113 +static void
29.114 + plover_transaction_helper_prepare_confirm(PloverTransactionHelper *helper)
29.115 +{
29.116 + gchar *package_list,*add,*remove,*s;
29.117 + GtkLabel *label;
29.118 + struct plover_vector *report;
29.119 + if (helper->report_adding->len)
29.120 + {
29.121 + plover_vector_sort(helper->report_adding);
29.122 + if (helper->report_adding_dependencies)
29.123 + {
29.124 + report=plover_vector_dup(helper->report_adding);
29.125 + if (helper->report_adding->len==1)
29.126 + plover_vector_append(report,"its dependencies");
29.127 + else
29.128 + plover_vector_append(report,"their dependencies");
29.129 + package_list=plover_vector_format_for_display(report);
29.130 + plover_vector_free(report);
29.131 + }
29.132 + else
29.133 + package_list=
29.134 + plover_vector_format_for_display(helper->report_adding);
29.135 + add=g_strconcat("Packages to be installed or updated: ",package_list,
29.136 + ".",NULL);
29.137 + g_free(package_list);
29.138 + }
29.139 + else
29.140 + add=NULL;
29.141 + if (helper->report_removing->len)
29.142 + {
29.143 + plover_vector_sort(helper->report_removing);
29.144 + if (helper->report_removing_dependants)
29.145 + {
29.146 + report=plover_vector_dup(helper->report_removing);
29.147 + if (helper->report_adding->len==1)
29.148 + plover_vector_append(report,"its dependants");
29.149 + else
29.150 + plover_vector_append(report,"their dependants");
29.151 + package_list=plover_vector_format_for_display(report);
29.152 + plover_vector_free(report);
29.153 + }
29.154 + else
29.155 + package_list=
29.156 + plover_vector_format_for_display(helper->report_removing);
29.157 + remove=g_strconcat("Packages to be removed: ",package_list,".",NULL);
29.158 + g_free(package_list);
29.159 + }
29.160 + else
29.161 + remove=NULL;
29.162 + label=GTK_LABEL(gtk_builder_get_object(helper->ui,"SISummaryOfWork"));
29.163 + if (add && remove)
29.164 + s=g_strconcat("<b>Installation Summary</b>\n\n",remove,"\n\n",add,NULL);
29.165 + else if (add || remove)
29.166 + s=g_strconcat("<b>Installation Summary</b>\n\n",add?add:remove,NULL);
29.167 + else
29.168 + s=g_strdup("<b>Installation Summary</b>\n\nNo changes scheduled");
29.169 + gtk_label_set_markup(label,s);
29.170 + g_free(s);
29.171 + g_free(add);
29.172 + g_free(remove);
29.173 +}
29.174 +
29.175 +static void plover_transaction_helper_run(PloverTransactionHelper *helper);
29.176 +
29.177 +static void plover_transaction_helper_callback(GObject *source,
29.178 + GAsyncResult *result,gpointer user_data)
29.179 +{
29.180 + GError *error=NULL;
29.181 + PloverTransactionHelper *helper=user_data;
29.182 + PloverTransaction *transaction=PLOVER_TRANSACTION(source);
29.183 + if (!plover_transaction_commit_finish(transaction,result,&error))
29.184 + {
29.185 + plover_transaction_helper_set_error(helper,error,
29.186 + "Software installation failed");
29.187 + g_error_free(error);
29.188 + }
29.189 + else
29.190 + plover_transaction_helper_run(helper);
29.191 + g_signal_handlers_disconnect_by_data(transaction,helper);
29.192 + g_object_unref(transaction);
29.193 +}
29.194 +
29.195 +static void plover_transaction_helper_transaction_status_changed(
29.196 + PloverTransaction *transaction,const char *status,
29.197 + PloverTransactionHelper *helper)
29.198 +{
29.199 + GtkProgressBar *bar;
29.200 + bar=GTK_PROGRESS_BAR(gtk_builder_get_object(helper->ui,"SIProgressBar"));
29.201 + gtk_progress_bar_set_text(bar,status);
29.202 +}
29.203 +
29.204 +static void plover_transaction_helper_run(PloverTransactionHelper *helper)
29.205 +{
29.206 + PloverTransaction *transaction;
29.207 + GtkWidget *page;
29.208 + page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgress"));
29.209 + if (helper->transactions)
29.210 + {
29.211 + if (helper->assistant)
29.212 + gtk_assistant_set_page_complete(helper->assistant,page,FALSE);
29.213 + transaction=helper->transactions->data;
29.214 + helper->transactions=g_slist_delete_link(helper->transactions,
29.215 + helper->transactions);
29.216 + g_signal_connect(transaction,"status-changed",
29.217 + G_CALLBACK(plover_transaction_helper_transaction_status_changed),
29.218 + helper);
29.219 + plover_transaction_commit_async(transaction,NULL,
29.220 + plover_transaction_helper_callback,helper);
29.221 + }
29.222 + else if (helper->assistant)
29.223 + gtk_assistant_set_page_complete(helper->assistant,page,TRUE);
29.224 +}
29.225 +
29.226 +static gboolean plover_transaction_helper_pulse(gpointer user_data)
29.227 +{
29.228 + PloverTransactionHelper *helper=user_data;
29.229 + GtkWidget *w;
29.230 + GtkProgressBar *bar;
29.231 + if (!helper->assistant)
29.232 + return FALSE;
29.233 + w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgress"));
29.234 + bar=GTK_PROGRESS_BAR(gtk_builder_get_object(helper->ui,"SIProgressBar"));
29.235 + if (gtk_assistant_get_page_complete(helper->assistant,w))
29.236 + {
29.237 + gtk_progress_bar_set_fraction(bar,1.0);
29.238 + helper->pulse_handler=0;
29.239 + return FALSE;
29.240 + }
29.241 + else
29.242 + {
29.243 + gtk_progress_bar_pulse(bar);
29.244 + return TRUE;
29.245 + }
29.246 +}
29.247 +
29.248 +static void
29.249 + plover_transaction_helper_prepare_progress(PloverTransactionHelper *helper)
29.250 +{
29.251 + GError *error=NULL;
29.252 + GtkToggleButton *button;
29.253 + PloverTransaction *transaction;
29.254 + button=GTK_TOGGLE_BUTTON(gtk_builder_get_object(helper->ui,
29.255 + "SIRemoveExisting"));
29.256 + if (gtk_toggle_button_get_active(button))
29.257 + {
29.258 + transaction=plover_transaction_new_remove(NULL,&error);
29.259 + if (!transaction)
29.260 + {
29.261 + if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT))
29.262 + g_clear_error(&error);
29.263 + if (error)
29.264 + {
29.265 + plover_transaction_helper_set_error(helper,error,
29.266 + "Software installation failed");
29.267 + g_error_free(error);
29.268 + return;
29.269 + }
29.270 + }
29.271 + else
29.272 + helper->transactions=
29.273 + g_slist_prepend(helper->transactions,transaction);
29.274 + }
29.275 + /*
29.276 + * Note that PloverTransaction does support cancelling a transaction, but
29.277 + * there are a number of challenges with using it:
29.278 + * - cancellation is only supported during the file phase if razor
29.279 + * has atomic rollback,
29.280 + * - cancellation is not supported during post-transaction scripts at all
29.281 + * (since by the time the first script is started the atomic has already
29.282 + * been committed) and these can take quite some time,
29.283 + * - where a transaction has an embedded COMMIT, any rollback won't
29.284 + * go back beyond this point.
29.285 + * To support user-cancel, then, we would need some mechanism to:
29.286 + * - Comunicate that the operation is being cancelled and this may take
29.287 + * some time,
29.288 + * - Not allow cancellation at all after the last post-transaction script
29.289 + * phase is started,
29.290 + * - Report the partially completed transaction where cancellation
29.291 + * occurred after a COMMIT point.
29.292 + * At present, this doesn't appear worth the effort.
29.293 + */
29.294 + if (helper->assistant)
29.295 + gtk_assistant_commit(helper->assistant);
29.296 + plover_transaction_helper_run(helper);
29.297 + helper->pulse_handler=g_timeout_add(100,plover_transaction_helper_pulse,
29.298 + helper);
29.299 +}
29.300 +
29.301 +static void plover_transaction_helper_assistant_prepare(GtkAssistant *assistant,
29.302 + GtkWidget *page,PloverTransactionHelper *helper)
29.303 +{
29.304 + if (page==GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm")))
29.305 + plover_transaction_helper_prepare_confirm(helper);
29.306 + else if (page==GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgress")))
29.307 + plover_transaction_helper_prepare_progress(helper);
29.308 +}
29.309 +
29.310 +static void
29.311 + plover_transaction_helper_remove_existing_toggled(GtkToggleButton *button,
29.312 + PloverTransactionHelper *helper)
29.313 +{
29.314 + GtkWidget *w;
29.315 + if (helper->assistant)
29.316 + {
29.317 + w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm"));
29.318 + gtk_assistant_set_page_complete(helper->assistant,w,
29.319 + gtk_toggle_button_get_active(button));
29.320 + }
29.321 +}
29.322 +
29.323 +PloverTransactionHelper *plover_transaction_helper_new(GtkBuilder *ui)
29.324 +{
29.325 + gsize len;
29.326 + gchar *s,*directory,*contents;
29.327 + GError *error=NULL;
29.328 + GtkWidget *w;
29.329 + PloverTransactionHelper *helper;
29.330 + g_return_val_if_fail(ui == NULL || GTK_IS_BUILDER(ui),NULL);
29.331 + helper=PLOVER_TRANSACTION_HELPER(
29.332 + g_object_new(PLOVER_TYPE_TRANSACTION_HELPER,NULL));
29.333 + if (ui)
29.334 + helper->ui=g_object_ref(ui);
29.335 + else
29.336 + helper->ui=gtk_builder_new();
29.337 + helper->assistant=
29.338 + GTK_ASSISTANT(gtk_builder_get_object(helper->ui,"SoftwareInstallation"));
29.339 + if (!helper->assistant)
29.340 + {
29.341 + directory=g_strdup(g_getenv("PLOVER_DATADIR"));
29.342 + if (!directory)
29.343 + {
29.344 +#ifdef WIN32
29.345 + s=g_win32_get_package_installation_directory_of_module(NULL);
29.346 + directory=g_build_filename(s,"share","plover",NULL);
29.347 + g_free(s);
29.348 +#else
29.349 + directory=g_strdup(PLOVER_DATADIR);
29.350 +#endif
29.351 + }
29.352 + s=g_build_filename(directory,"software-installation.ui",NULL);
29.353 + g_free(directory);
29.354 + (void)g_file_get_contents(s,&contents,&len,&error);
29.355 + g_free(s);
29.356 + if (!error)
29.357 + {
29.358 + (void)gtk_builder_add_from_string(helper->ui,contents,len,&error);
29.359 + g_free(contents);
29.360 + }
29.361 + if (error)
29.362 + {
29.363 + g_critical("software-installation.ui: %s",error->message);
29.364 + g_clear_error(&error);
29.365 + g_set_error(&error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
29.366 + "Internal error (no user interface)");
29.367 + plover_transaction_helper_set_error(helper,error,
29.368 + "Can't start installer");
29.369 + return helper;
29.370 + }
29.371 + helper->assistant=GTK_ASSISTANT(gtk_builder_get_object(helper->ui,
29.372 + "SoftwareInstallation"));
29.373 + }
29.374 + if (!helper->assistant)
29.375 + {
29.376 + g_critical("\"SoftwareInstallation\" object not found");
29.377 + g_set_error(&error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
29.378 + "Internal error (missing wizard)");
29.379 + plover_transaction_helper_set_error(helper,error,
29.380 + "Can't start installer");
29.381 + g_error_free(error);
29.382 + return helper;
29.383 + }
29.384 + else
29.385 + g_object_ref(helper->assistant);
29.386 + if (!GTK_IS_ASSISTANT(helper->assistant))
29.387 + {
29.388 + g_critical("\"SoftwareInstallation\" is not a GtkAssistant");
29.389 + g_set_error(&error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
29.390 + "Internal error (unexpected wizard type)");
29.391 + plover_transaction_helper_set_error(helper,error,
29.392 + "Can't start installer");
29.393 + g_error_free(error);
29.394 + return helper;
29.395 + }
29.396 + g_signal_connect(helper->assistant,"cancel",
29.397 + G_CALLBACK(plover_transaction_helper_assistant_cancel),helper);
29.398 + g_signal_connect(helper->assistant,"close",
29.399 + G_CALLBACK(plover_transaction_helper_assistant_close),helper);
29.400 + g_signal_connect(helper->assistant,"prepare",
29.401 + G_CALLBACK(plover_transaction_helper_assistant_prepare),helper);
29.402 + w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIRemoveExisting"));
29.403 + if (w)
29.404 + g_signal_connect(w,"toggled",
29.405 + G_CALLBACK(plover_transaction_helper_remove_existing_toggled),helper);
29.406 + w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIIntroduction"));
29.407 + if (w)
29.408 + gtk_assistant_set_page_complete(helper->assistant,w,TRUE);
29.409 + return helper;
29.410 +}
29.411 +
29.412 +PloverPackageSet *
29.413 + plover_transaction_helper_get_installed(PloverTransactionHelper *helper)
29.414 +{
29.415 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.416 + return helper->installed;
29.417 +}
29.418 +
29.419 +void plover_transaction_helper_set_installed(PloverTransactionHelper *helper,
29.420 + PloverPackageSet *installed)
29.421 +{
29.422 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.423 + g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed));
29.424 + g_return_if_fail(helper->installed == NULL);
29.425 + helper->installed=g_object_ref(installed);
29.426 +}
29.427 +
29.428 +PloverRepository *
29.429 + plover_transaction_helper_get_upstream(PloverTransactionHelper *helper,
29.430 + GError **error)
29.431 +{
29.432 + const char *base;
29.433 +#if 0
29.434 + const char *prefix;
29.435 + struct razor_relocations *relocations=NULL;
29.436 +#endif
29.437 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.438 + if (!helper->upstream)
29.439 + {
29.440 +#if 0
29.441 + prefix=plover_transaction_helper_get_prefix(helper,error);
29.442 + if (!prefix)
29.443 + return NULL;
29.444 +#endif
29.445 + base=plover_transaction_helper_get_base(helper);
29.446 +#if 0
29.447 + if (prefix)
29.448 + {
29.449 + relocations=razor_relocations_create();
29.450 + razor_relocations_add(relocations,"/usr",prefix);
29.451 + }
29.452 +#endif
29.453 + helper->upstream=plover_repository_new_from_yum(base,error);
29.454 +#if 0
29.455 + if (relocations)
29.456 + razor_relocations_destroy(relocations);
29.457 +#endif
29.458 + }
29.459 + return helper->upstream;
29.460 +}
29.461 +
29.462 +static PloverPackageSet *plover_transaction_helper_get_relocated_upstream(
29.463 + PloverTransactionHelper *helper,GError **error)
29.464 +{
29.465 + const char *prefix;
29.466 + struct razor_relocations *relocations=NULL;
29.467 + GError *tmp_error=NULL;
29.468 + PloverRepository *upstream;
29.469 + PloverPackageSet *set;
29.470 + if (!helper->relocated_upstream)
29.471 + {
29.472 + upstream=plover_transaction_helper_get_upstream(helper,error);
29.473 + if (!upstream)
29.474 + return NULL;
29.475 + prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
29.476 + if (tmp_error)
29.477 + {
29.478 + g_propagate_error(error,tmp_error);
29.479 + return NULL;
29.480 + }
29.481 + set=plover_repository_get_package_set(upstream);
29.482 + if (prefix)
29.483 + {
29.484 + relocations=razor_relocations_create();
29.485 + razor_relocations_add(relocations,"/usr",prefix);
29.486 + helper->relocated_upstream=
29.487 + plover_package_set_new_from_repository(upstream,relocations,
29.488 + error);
29.489 + if (relocations)
29.490 + razor_relocations_destroy(relocations);
29.491 + }
29.492 + else
29.493 + helper->relocated_upstream=g_object_ref(set);
29.494 + }
29.495 + return helper->relocated_upstream;
29.496 +}
29.497 +
29.498 +void plover_transaction_helper_set_upstream(PloverTransactionHelper *helper,
29.499 + PloverRepository *upstream)
29.500 +{
29.501 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.502 + g_return_if_fail(PLOVER_IS_REPOSITORY(upstream));
29.503 + g_return_if_fail(helper->upstream == NULL);
29.504 + helper->upstream=g_object_ref(upstream);
29.505 +}
29.506 +
29.507 +const char *plover_transaction_helper_get_base(PloverTransactionHelper *helper)
29.508 +{
29.509 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.510 + return helper->base;
29.511 +}
29.512 +
29.513 +void plover_transaction_helper_set_base(PloverTransactionHelper *helper,
29.514 + const char *base)
29.515 +{
29.516 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.517 + g_return_if_fail(helper->transactions == NULL);
29.518 + g_free(helper->base);
29.519 + helper->base=g_strdup(base);
29.520 +}
29.521 +
29.522 +struct comps *
29.523 + plover_transaction_helper_get_comps(PloverTransactionHelper *helper,
29.524 + GError **error)
29.525 +{
29.526 + gchar *s;
29.527 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.528 + g_return_val_if_fail(helper->base != NULL,NULL);
29.529 + if (!helper->comps)
29.530 + {
29.531 + s=g_strconcat(helper->base,"/repodata/comps.xml",NULL);
29.532 + helper->comps=plover_comps_new_from_file(s);
29.533 + if (!helper->comps)
29.534 + g_set_error(error,PLOVER_GENERAL_ERROR,
29.535 + PLOVER_GENERAL_ERROR_FAILED,"%s: %s",s,g_strerror(errno));
29.536 + g_free(s);
29.537 + }
29.538 + return helper->comps;
29.539 +}
29.540 +
29.541 +const char *
29.542 + plover_transaction_helper_get_prefix(PloverTransactionHelper *helper,
29.543 + GError **error)
29.544 +{
29.545 + const char *prefix;
29.546 + struct comps *comps;
29.547 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.548 + g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL);
29.549 + if (helper->base)
29.550 + {
29.551 + comps=plover_transaction_helper_get_comps(helper,error);
29.552 + if (!comps)
29.553 + return NULL;
29.554 + return plover_default_prefix_for_vendor(comps->vendor);
29.555 + }
29.556 + prefix=plover_package_set_guess_prefix(helper->installed,error);
29.557 + return prefix;
29.558 +}
29.559 +
29.560 +static int plover_transaction_helper_package_count(void)
29.561 +{
29.562 + int count=0;
29.563 + char *install_root;
29.564 + struct razor_set *set;
29.565 + struct razor_package *package;
29.566 + struct razor_package_iterator *pi;
29.567 + install_root=getenv("RAZOR_ROOT");
29.568 + if (!install_root)
29.569 + install_root="";
29.570 + set=razor_root_open_read_only(install_root,NULL);
29.571 + if (set)
29.572 + {
29.573 + pi=razor_package_iterator_create(set);
29.574 + while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
29.575 + count++;
29.576 + razor_package_iterator_destroy(pi);
29.577 + razor_set_unref(set);
29.578 + }
29.579 + return count;
29.580 +}
29.581 +
29.582 +static gboolean
29.583 + plover_transaction_helper_check_vendor(PloverTransactionHelper *helper,
29.584 + GError **error)
29.585 +{
29.586 + int i;
29.587 + gchar *prefix=NULL,*s;
29.588 + struct comps *comps=NULL;
29.589 + GtkWidget *container,*page;
29.590 + GtkButton *button;
29.591 + GtkLabel *label;
29.592 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.593 + if (helper->check_vendor)
29.594 + {
29.595 + comps=plover_transaction_helper_get_comps(helper,error);
29.596 + if (!comps)
29.597 + return FALSE;
29.598 + prefix=plover_default_prefix_for_vendor(comps->vendor);
29.599 + }
29.600 + button=GTK_BUTTON(gtk_builder_get_object(helper->ui,"SIRemoveExisting"));
29.601 + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
29.602 + container=GTK_WIDGET(gtk_builder_get_object(helper->ui,
29.603 + "SIIncompatibleInstallation"));
29.604 + page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm"));
29.605 + if (helper->check_vendor && prefix &&
29.606 + !plover_installed_files_match_prefix(prefix))
29.607 + {
29.608 + label=GTK_LABEL(gtk_builder_get_object(helper->ui,
29.609 + "SIIncompatibleInstallationLabel"));
29.610 + s=g_strdup_printf("<b>Incompatible Installation</b>\n\n"
29.611 + "The existing installation is not from %s.\n"
29.612 + "In order to continue, all the existing packages must be removed.",
29.613 + comps->vendor);
29.614 + gtk_label_set_markup(label,s);
29.615 + g_free(s);
29.616 + i=plover_transaction_helper_package_count();
29.617 + s=g_strdup_printf("Remove %d existing package%s",i,i==1?"":"s");
29.618 + gtk_button_set_label(button,s);
29.619 + g_free(s);
29.620 + gtk_widget_show(container);
29.621 + if (helper->assistant)
29.622 + gtk_assistant_set_page_complete(helper->assistant,page,FALSE);
29.623 + }
29.624 + else
29.625 + {
29.626 + gtk_widget_hide(container);
29.627 + if (helper->assistant)
29.628 + gtk_assistant_set_page_complete(helper->assistant,page,TRUE);
29.629 + }
29.630 + return TRUE;
29.631 +}
29.632 +
29.633 +void plover_transaction_helper_set_check_vendor(PloverTransactionHelper *helper,
29.634 + gboolean check_vendor)
29.635 +{
29.636 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.637 + if (helper->check_vendor!=check_vendor)
29.638 + {
29.639 + helper->check_vendor=check_vendor;
29.640 + if (helper->transactions)
29.641 + plover_transaction_helper_check_vendor(helper,NULL);
29.642 + }
29.643 +}
29.644 +
29.645 +/*
29.646 + * If plover_transaction_helper_add_transaction() failes with an error
29.647 + * of PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET
29.648 + * then plover_transaction_helper_get_unsatisfied() can be used to
29.649 + * retrieve a textual description of the problem.
29.650 + */
29.651 +
29.652 +const char *
29.653 + plover_transaction_helper_get_unsatisfied(PloverTransactionHelper *helper)
29.654 +{
29.655 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.656 + return helper->unsatisfied;
29.657 +}
29.658 +
29.659 +gboolean
29.660 + plover_transaction_helper_add_transaction(PloverTransactionHelper *helper,
29.661 + PloverTransaction *transaction,struct plover_vector *report_packages,
29.662 + enum razor_install_action report_action,GError **error)
29.663 +{
29.664 + int i,count;
29.665 + gboolean other_packages;
29.666 + const char *s,*name;
29.667 + enum razor_install_action action;
29.668 + struct razor_install_iterator *ii;
29.669 + struct razor_set *next;
29.670 + struct razor_package *package;
29.671 + struct plover_vector *tasked_packages;
29.672 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.673 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
29.674 + g_return_val_if_fail(report_action==RAZOR_INSTALL_ACTION_ADD || report_action==RAZOR_INSTALL_ACTION_REMOVE,FALSE);
29.675 + g_free(helper->unsatisfied);
29.676 + helper->unsatisfied=NULL;
29.677 + if (!plover_transaction_resolve(transaction,error))
29.678 + {
29.679 + s=plover_transaction_get_unsatisfied(transaction);
29.680 + helper->unsatisfied=g_strdup(s);
29.681 + return FALSE;
29.682 + }
29.683 + ii=plover_transaction_get_install_iterator(transaction,error);
29.684 + if (!ii)
29.685 + return FALSE;
29.686 + next=plover_transaction_get_next_set(transaction,error);
29.687 + if (!next)
29.688 + return FALSE;
29.689 + tasked_packages=plover_vector_new();
29.690 + other_packages=FALSE;
29.691 + while (razor_install_iterator_next(ii,&package,&action,&count))
29.692 + {
29.693 + if (action==report_action)
29.694 + {
29.695 + razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
29.696 + RAZOR_DETAIL_LAST);
29.697 + if (!report_packages ||
29.698 + plover_vector_contains(report_packages,name))
29.699 + plover_vector_append(tasked_packages,name);
29.700 + else
29.701 + other_packages=TRUE;
29.702 + }
29.703 + }
29.704 + if (!tasked_packages->len)
29.705 + {
29.706 + /*
29.707 + * If there are no reportable packages tasked for action there
29.708 + * shouldn't by any packages at all, but let's be paranoid.
29.709 + */
29.710 + other_packages=FALSE;
29.711 + razor_install_iterator_rewind(ii);
29.712 + while (razor_install_iterator_next(ii,&package,&action,&count))
29.713 + {
29.714 + if (action==report_action)
29.715 + {
29.716 + razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
29.717 + RAZOR_DETAIL_LAST);
29.718 + plover_vector_append(tasked_packages,name);
29.719 + }
29.720 + }
29.721 + }
29.722 + if (!tasked_packages->len)
29.723 + {
29.724 + g_set_error(error,PLOVER_GENERAL_ERROR,
29.725 + PLOVER_GENERAL_ERROR_NO_WORK,"Transaction includes no %s actions",
29.726 + report_action==RAZOR_INSTALL_ACTION_ADD?"add":"remove");
29.727 + plover_vector_free(tasked_packages);
29.728 + return FALSE;
29.729 + }
29.730 + if (!helper->transactions)
29.731 + plover_transaction_helper_check_vendor(helper,error);
29.732 + g_object_ref(transaction);
29.733 + helper->transactions=g_slist_append(helper->transactions,transaction);
29.734 + if (report_action==RAZOR_INSTALL_ACTION_ADD)
29.735 + {
29.736 + for(i=0;i<tasked_packages->len;i++)
29.737 + {
29.738 + s=tasked_packages->strings[i];
29.739 + if (!plover_vector_contains(helper->report_adding,s))
29.740 + plover_vector_append(helper->report_adding,s);
29.741 + }
29.742 + helper->report_adding_dependencies|=other_packages;
29.743 + }
29.744 + else
29.745 + {
29.746 + for(i=0;i<tasked_packages->len;i++)
29.747 + {
29.748 + s=tasked_packages->strings[i];
29.749 + if (!plover_vector_contains(helper->report_removing,s))
29.750 + plover_vector_append(helper->report_removing,s);
29.751 + }
29.752 + helper->report_removing_dependants|=other_packages;
29.753 + }
29.754 + plover_vector_free(tasked_packages);
29.755 + return TRUE;
29.756 +}
29.757 +
29.758 +static PloverTransaction *
29.759 + plover_transaction_helper_new_transaction(PloverTransactionHelper *helper,
29.760 + GError **error)
29.761 +{
29.762 + gboolean ok;
29.763 + const char *base,*prefix;
29.764 + GError *tmp_error=NULL;
29.765 + PloverTransaction *transaction;
29.766 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
29.767 + prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
29.768 + if (tmp_error)
29.769 + {
29.770 + g_propagate_error(error,tmp_error);
29.771 + return NULL;
29.772 + }
29.773 + transaction=plover_transaction_new();
29.774 + plover_transaction_set_prefix(transaction,prefix);
29.775 + plover_transaction_set_installed(transaction,helper->installed);
29.776 + if (helper->upstream)
29.777 + ok=plover_transaction_set_upstream(transaction,helper->upstream,error);
29.778 + else
29.779 + {
29.780 + base=plover_transaction_helper_get_base(helper);
29.781 + ok=plover_transaction_set_upstream_from_yum(transaction,base,error);
29.782 + }
29.783 + if (!ok)
29.784 + {
29.785 + g_object_unref(transaction);
29.786 + transaction=NULL;
29.787 + }
29.788 + return transaction;
29.789 +}
29.790 +
29.791 +struct plover_vector *plover_transaction_helper_group_get_default_packages(
29.792 + PloverTransactionHelper *helper,const char *group,GError **error)
29.793 +{
29.794 + gboolean changed;
29.795 + struct comps *comps;
29.796 + struct comps_group *grp;
29.797 + struct comps_requirement *pkg;
29.798 + struct plover_vector *default_packages;
29.799 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.800 + comps=plover_transaction_helper_get_comps(helper,error);
29.801 + if (!comps)
29.802 + return NULL;
29.803 + grp=plover_comps_lookup_group(comps,group);
29.804 + if (!grp)
29.805 + {
29.806 + g_set_error(error,PLOVER_GENERAL_ERROR,
29.807 + PLOVER_GENERAL_ERROR_FAILED,"%s: group not found",group);
29.808 + return NULL;
29.809 + }
29.810 + default_packages=plover_vector_new();
29.811 + do
29.812 + {
29.813 + changed=FALSE;
29.814 + for(pkg=grp->packages;pkg;pkg=pkg->next)
29.815 + {
29.816 + if (plover_vector_contains(default_packages,pkg->name))
29.817 + continue;
29.818 + if (pkg->type==COMPS_REQUIREMENT_DEFAULT ||
29.819 + pkg->type==COMPS_REQUIREMENT_MANDATORY ||
29.820 + pkg->type==COMPS_REQUIREMENT_CONDITIONAL &&
29.821 + plover_vector_contains(default_packages,pkg->requires))
29.822 + {
29.823 + changed=TRUE;
29.824 + plover_vector_append(default_packages,pkg->name);
29.825 + }
29.826 + }
29.827 + } while(changed);
29.828 + return default_packages;
29.829 +}
29.830 +
29.831 +/*
29.832 + * Returns TRUE if there is work to be done or FALSE if the packages are
29.833 + * already installed or on error.
29.834 + */
29.835 +gboolean
29.836 + plover_transaction_helper_install_packages(PloverTransactionHelper *helper,
29.837 + struct plover_vector *packages,GError **error)
29.838 +{
29.839 + gboolean retval;
29.840 + PloverTransaction *transaction;
29.841 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.842 + g_return_val_if_fail(packages != NULL,FALSE);
29.843 + if (!packages->len)
29.844 + {
29.845 + g_set_error(error,PLOVER_GENERAL_ERROR,
29.846 + PLOVER_GENERAL_ERROR_NO_WORK,"No packages listed to be installed");
29.847 + return FALSE;
29.848 + }
29.849 + transaction=plover_transaction_helper_new_transaction(helper,error);
29.850 + if (!transaction)
29.851 + return FALSE;
29.852 + if (!plover_transaction_install(transaction,packages->strings,error))
29.853 + {
29.854 + g_object_unref(transaction);
29.855 + return FALSE;
29.856 + }
29.857 + retval=plover_transaction_helper_add_transaction(helper,transaction,
29.858 + packages,RAZOR_INSTALL_ACTION_ADD,error);
29.859 + g_object_unref(transaction);
29.860 + return retval;
29.861 +}
29.862 +
29.863 +/*
29.864 + * Returns TRUE if there is work to be done or FALSE if the group is
29.865 + * already installed or on error.
29.866 + */
29.867 +gboolean
29.868 + plover_transaction_helper_install_group(PloverTransactionHelper *helper,
29.869 + const char *group,GError **error)
29.870 +{
29.871 + gboolean retval;
29.872 + struct plover_vector *selected_packages;
29.873 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.874 + selected_packages=plover_transaction_helper_group_get_default_packages(
29.875 + helper,group,error);
29.876 + if (!selected_packages)
29.877 + return FALSE;
29.878 + if (!selected_packages->len)
29.879 + {
29.880 + g_set_error(error,PLOVER_GENERAL_ERROR,
29.881 + PLOVER_GENERAL_ERROR_FAILED,"%s: no default packages",group);
29.882 + plover_vector_free(selected_packages);
29.883 + return FALSE;
29.884 + }
29.885 + retval=plover_transaction_helper_install_packages(helper,selected_packages,
29.886 + error);
29.887 + plover_vector_free(selected_packages);
29.888 + return retval;
29.889 +}
29.890 +
29.891 +/*
29.892 + * Returns TRUE if there is work to be done or FALSE if the group is
29.893 + * not installed or on error.
29.894 + */
29.895 +gboolean plover_transaction_helper_remove_group(PloverTransactionHelper *helper,
29.896 + const char *group,GError **error)
29.897 +{
29.898 + gboolean retval;
29.899 + struct plover_vector *selected_packages;
29.900 + PloverTransaction *transaction;
29.901 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.902 + selected_packages=plover_transaction_helper_group_get_default_packages(
29.903 + helper,group,error);
29.904 + if (!selected_packages)
29.905 + return FALSE;
29.906 + if (!selected_packages->len)
29.907 + {
29.908 + g_set_error(error,PLOVER_GENERAL_ERROR,
29.909 + PLOVER_GENERAL_ERROR_FAILED,"%s: no default packages",group);
29.910 + plover_vector_free(selected_packages);
29.911 + return FALSE;
29.912 + }
29.913 + transaction=plover_transaction_new();
29.914 + plover_transaction_set_installed(transaction,helper->installed);
29.915 + if (!plover_transaction_remove(transaction,selected_packages->strings,
29.916 + error))
29.917 + {
29.918 + plover_vector_free(selected_packages);
29.919 + g_object_unref(transaction);
29.920 + return FALSE;
29.921 + }
29.922 + retval=plover_transaction_helper_add_transaction(helper,transaction,
29.923 + NULL,RAZOR_INSTALL_ACTION_REMOVE,error);
29.924 + g_object_unref(transaction);
29.925 + plover_vector_free(selected_packages);
29.926 + return retval;
29.927 +}
29.928 +
29.929 +/*
29.930 + * Returns TRUE if there is work to be done or FALSE if all updates have
29.931 + * already been applied or on error.
29.932 + */
29.933 +gboolean plover_transaction_helper_update(PloverTransactionHelper *helper,
29.934 + GError **error)
29.935 +{
29.936 + gboolean retval;
29.937 + PloverTransaction *transaction;
29.938 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.939 + transaction=plover_transaction_helper_new_transaction(helper,error);
29.940 + if (!transaction)
29.941 + return FALSE;
29.942 + if (!plover_transaction_update(transaction,NULL,error))
29.943 + {
29.944 + g_object_unref(transaction);
29.945 + return FALSE;
29.946 + }
29.947 + retval=plover_transaction_helper_add_transaction(helper,transaction,
29.948 + NULL,RAZOR_INSTALL_ACTION_ADD,error);
29.949 + g_object_unref(transaction);
29.950 + return retval;
29.951 +}
29.952 +
29.953 +gboolean plover_transaction_helper_get_visible(PloverTransactionHelper *helper)
29.954 +{
29.955 + g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
29.956 + if (helper->error_dialog)
29.957 + return TRUE;
29.958 + else if (!helper->assistant)
29.959 + return FALSE;
29.960 + else
29.961 + return gtk_widget_get_visible(GTK_WIDGET(helper->assistant));
29.962 +}
29.963 +
29.964 +void plover_transaction_helper_present(PloverTransactionHelper *helper)
29.965 +{
29.966 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.967 + if (helper->error_dialog)
29.968 + gtk_window_present(GTK_WINDOW(helper->error_dialog));
29.969 + else if (helper->assistant)
29.970 + gtk_window_present(GTK_WINDOW(helper->assistant));
29.971 +}
29.972 +
29.973 +static void
29.974 + plover_transaction_helper_error_dialog_response(GtkDialog *error_dialog,
29.975 + int response_id,PloverTransactionHelper *helper)
29.976 +{
29.977 + g_signal_handlers_disconnect_by_data(error_dialog,helper);
29.978 + if ((GtkWidget *)error_dialog==helper->error_dialog)
29.979 + {
29.980 + gtk_widget_destroy(helper->error_dialog);
29.981 + helper->error_dialog=NULL;
29.982 + if (helper->assistant)
29.983 + {
29.984 + gtk_widget_hide(GTK_WIDGET(helper->assistant));
29.985 + gtk_assistant_set_current_page(helper->assistant,0);
29.986 + }
29.987 + g_signal_emit(helper,signals[CLOSE],0);
29.988 + }
29.989 +}
29.990 +
29.991 +const char *plover_transaction_helper_get_error(PloverTransactionHelper *helper,
29.992 + const GError **error)
29.993 +{
29.994 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.995 + if (!helper->error_dialog)
29.996 + return NULL;
29.997 + if (error)
29.998 + *error=helper->error;
29.999 + return helper->error_primary_text;
29.1000 +}
29.1001 +
29.1002 +void plover_transaction_helper_set_error(PloverTransactionHelper *helper,
29.1003 + const GError *error,const char *primary_text)
29.1004 +{
29.1005 + GtkMessageType type;
29.1006 + GtkWindow *window;
29.1007 + g_return_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper));
29.1008 + g_return_if_fail(error != NULL);
29.1009 + g_return_if_fail(primary_text != NULL);
29.1010 + if (helper->pulse_handler)
29.1011 + {
29.1012 + g_source_remove(helper->pulse_handler);
29.1013 + helper->pulse_handler=0;
29.1014 + }
29.1015 + if (helper->error_dialog)
29.1016 + {
29.1017 + gtk_widget_destroy(helper->error_dialog);
29.1018 + helper->error_dialog=NULL;
29.1019 + }
29.1020 + g_free(helper->error_primary_text);
29.1021 + helper->error_primary_text=g_strdup(primary_text);
29.1022 + g_clear_error(&helper->error);
29.1023 + helper->error=g_error_copy(error);
29.1024 + if (g_error_matches(error,PLOVER_GENERAL_ERROR,
29.1025 + PLOVER_GENERAL_ERROR_NO_WORK))
29.1026 + type=GTK_MESSAGE_INFO;
29.1027 + else
29.1028 + type=GTK_MESSAGE_ERROR;
29.1029 + if (helper->assistant)
29.1030 + window=GTK_WINDOW(helper->assistant);
29.1031 + else
29.1032 + window=NULL;
29.1033 + helper->error_dialog=gtk_message_dialog_new(window,
29.1034 + GTK_DIALOG_DESTROY_WITH_PARENT,type,GTK_BUTTONS_CLOSE,primary_text);
29.1035 + gtk_message_dialog_format_secondary_text(
29.1036 + GTK_MESSAGE_DIALOG(helper->error_dialog),error->message);
29.1037 + gtk_widget_show(helper->error_dialog);
29.1038 + g_signal_connect(helper->error_dialog,"response",
29.1039 + G_CALLBACK(plover_transaction_helper_error_dialog_response),helper);
29.1040 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/plover-gtk/transactionhelper.h Sat Nov 15 19:04:45 2014 +0000
30.3 @@ -0,0 +1,102 @@
30.4 +#ifndef __PLOVER_TRANSACTION_HELPER_H__
30.5 +#define __PLOVER_TRANSACTION_HELPER_H__
30.6 +
30.7 +#include <gtk/gtk.h>
30.8 +#include <plover/packageset.h>
30.9 +#include <plover/repository.h>
30.10 +#include <plover/transaction.h>
30.11 +
30.12 +#define PLOVER_TYPE_TRANSACTION_HELPER plover_transaction_helper_get_type()
30.13 +#define PLOVER_TRANSACTION_HELPER(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
30.14 + PLOVER_TYPE_TRANSACTION_HELPER,\
30.15 + PloverTransactionHelper)
30.16 +#define PLOVER_TRANSACTION_HELPER_CLASS(klass) \
30.17 + G_TYPE_CHECK_CLASS_CAST(klass,\
30.18 + PLOVER_TYPE_TRANSACTION_HELPER,\
30.19 + PloverTransactionHelperClass)
30.20 +#define PLOVER_IS_TRANSACTION_HELPER(obj) \
30.21 + G_TYPE_CHECK_INSTANCE_TYPE(obj,\
30.22 + PLOVER_TYPE_TRANSACTION_HELPER)
30.23 +#define PLOVER_IS_TRANSACTION_HELPER_CLASS(klass) \
30.24 + G_TYPE_CHECK_CLASS_TYPE(obj,\
30.25 + PLOVER_TYPE_TRANSACTION_HELPER)
30.26 +#define PLOVER_TRANSACTION_HELPER_GET_CLASS(obj) \
30.27 + G_TYPE_INSTANCE_GET_CLASS(obj,\
30.28 + PLOVER_TYPE_TRANSACTION_HELPER,\
30.29 + PloverTransactionHelperClass)
30.30 +
30.31 +typedef struct _PloverTransactionHelper {
30.32 + GObject parent_instance;
30.33 + PloverPackageSet *installed;
30.34 + PloverRepository *upstream;
30.35 + PloverPackageSet *relocated_upstream;
30.36 + gchar *base;
30.37 + gchar *unsatisfied;
30.38 + struct comps *comps;
30.39 + gboolean check_vendor;
30.40 + gboolean report_adding_dependencies;
30.41 + gboolean report_removing_dependants;
30.42 + struct plover_vector *report_adding,*report_removing;
30.43 + GSList *transactions;
30.44 + GtkBuilder *ui;
30.45 + GtkAssistant *assistant;
30.46 + guint pulse_handler;
30.47 + GError *error;
30.48 + gchar *error_primary_text;
30.49 + GtkWidget *error_dialog;
30.50 +} PloverTransactionHelper;
30.51 +
30.52 +typedef struct _PloverTransactionHelperClass {
30.53 + GObjectClass parent_class;
30.54 +} PloverTransactionHelperClass;
30.55 +
30.56 +GType plover_transaction_helper_get_type(void);
30.57 +PloverTransactionHelper *plover_transaction_helper_new(GtkBuilder *ui);
30.58 +PloverPackageSet *
30.59 + plover_transaction_helper_get_installed(PloverTransactionHelper *helper);
30.60 +void plover_transaction_helper_set_installed(PloverTransactionHelper *helper,
30.61 + PloverPackageSet *installed);
30.62 +PloverRepository *
30.63 + plover_transaction_helper_get_upstream(PloverTransactionHelper *helper,
30.64 + GError **error);
30.65 +void plover_transaction_helper_set_upstream(PloverTransactionHelper *helper,
30.66 + PloverRepository *upstream);
30.67 +const char *plover_transaction_helper_get_base(PloverTransactionHelper *helper);
30.68 +void plover_transaction_helper_set_base(PloverTransactionHelper *helper,
30.69 + const char *base);
30.70 +struct comps *
30.71 + plover_transaction_helper_get_comps(PloverTransactionHelper *helper,
30.72 + GError **error);
30.73 +const char *
30.74 + plover_transaction_helper_get_prefix(PloverTransactionHelper *helper,
30.75 + GError **error);
30.76 +void plover_transaction_helper_set_check_vendor(PloverTransactionHelper *helper,
30.77 + gboolean check_vendor);
30.78 +const char *
30.79 + plover_transaction_helper_get_unsatisfied(PloverTransactionHelper *helper);
30.80 +gboolean
30.81 + plover_transaction_helper_add_transaction(PloverTransactionHelper *helper,
30.82 + PloverTransaction *transaction,struct plover_vector *report_packages,
30.83 + enum razor_install_action report_action,GError **error);
30.84 +struct plover_vector *plover_transaction_helper_group_get_default_packages(
30.85 + PloverTransactionHelper *helper,const char *group,GError **error);
30.86 +gboolean
30.87 + plover_transaction_helper_install_packages(PloverTransactionHelper *helper,
30.88 + struct plover_vector *packages,GError **error);
30.89 +gboolean
30.90 + plover_transaction_helper_install_group(PloverTransactionHelper *helper,
30.91 + const char *group,GError **error);
30.92 +gboolean
30.93 + plover_transaction_helper_remove_group(PloverTransactionHelper *helper,
30.94 + const char *group,GError **error);
30.95 +gboolean
30.96 + plover_transaction_helper_update(PloverTransactionHelper *helper,
30.97 + GError **error);
30.98 +gboolean plover_transaction_helper_get_visible(PloverTransactionHelper *helper);
30.99 +void plover_transaction_helper_present(PloverTransactionHelper *helper);
30.100 +const char *plover_transaction_helper_get_error(PloverTransactionHelper *helper,
30.101 + const GError **error);
30.102 +void plover_transaction_helper_set_error(PloverTransactionHelper *helper,
30.103 + const GError *error,const char *primary_text);
30.104 +
30.105 +#endif /* __PLOVER_TRANSACTION_HELPER_H__ */
31.1 --- a/plover/Makefile.am Fri Mar 23 20:29:50 2012 +0000
31.2 +++ b/plover/Makefile.am Sat Nov 15 19:04:45 2014 +0000
31.3 @@ -3,10 +3,11 @@
31.4 INCLUDES=-I$(top_srcdir)
31.5 AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO)
31.6
31.7 -pkginclude_HEADERS=plover.h
31.8 +pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h
31.9
31.10 lib_LTLIBRARIES=libplover.la
31.11 -libplover_la_SOURCES=$(pkginclude_HEADERS) util.c import-yum.c razor.c comps.c
31.12 +libplover_la_SOURCES=$(pkginclude_HEADERS) util.c import-yum.c razor.c comps.c \
31.13 + log.c vector.c transaction.c package.c packageset.c repository.c
31.14
31.15 pkgconfigdir=$(libdir)/pkgconfig
31.16 pkgconfig_DATA=plover.pc
32.1 --- a/plover/import-yum.c Fri Mar 23 20:29:50 2012 +0000
32.2 +++ b/plover/import-yum.c Sat Nov 15 19:04:45 2014 +0000
32.3 @@ -1,7 +1,7 @@
32.4 /*
32.5 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
32.6 * Copyright (C) 2008 Red Hat, Inc
32.7 - * Copyright (C) 2009, 2011 J. Ali Harlow <ali@juiblex.co.uk>
32.8 + * Copyright (C) 2009, 2011, 2014 J. Ali Harlow <ali@juiblex.co.uk>
32.9 *
32.10 * This program is free software; you can redistribute it and/or modify
32.11 * it under the terms of the GNU General Public License as published by
32.12 @@ -28,6 +28,7 @@
32.13 #include <fcntl.h>
32.14 #include <errno.h>
32.15
32.16 +#include <glib.h>
32.17 #include <expat.h>
32.18 #include <zlib.h>
32.19 #include <razor.h>
32.20 @@ -306,94 +307,110 @@
32.21
32.22 #define XML_BUFFER_SIZE 4096
32.23
32.24 -struct razor_set *
32.25 -plover_razor_set_create_from_yum(const char *base)
32.26 +struct razor_set *plover_razor_set_create_from_yum(const char *base,
32.27 + GError **error)
32.28 {
32.29 - struct yum_context ctx;
32.30 - void *buf;
32.31 - int len;
32.32 - gzFile primary, filelists;
32.33 - XML_ParsingStatus status;
32.34 - struct razor_set *set;
32.35 -
32.36 - ctx.importer = razor_importer_create();
32.37 - ctx.state = YUM_STATE_BEGIN;
32.38 -
32.39 - ctx.primary_parser = XML_ParserCreate(NULL);
32.40 - XML_SetUserData(ctx.primary_parser, &ctx);
32.41 - XML_SetElementHandler(ctx.primary_parser,
32.42 - yum_primary_start_element,
32.43 - yum_primary_end_element);
32.44 - XML_SetCharacterDataHandler(ctx.primary_parser,
32.45 - yum_character_data);
32.46 -
32.47 - ctx.filelists_parser = XML_ParserCreate(NULL);
32.48 - XML_SetUserData(ctx.filelists_parser, &ctx);
32.49 - XML_SetElementHandler(ctx.filelists_parser,
32.50 - yum_filelists_start_element,
32.51 - yum_filelists_end_element);
32.52 - XML_SetCharacterDataHandler(ctx.filelists_parser,
32.53 - yum_character_data);
32.54 -
32.55 - primary = gzopen("primary.xml.gz", "rb");
32.56 - if (primary == NULL)
32.57 - return NULL;
32.58 - filelists = gzopen("filelists.xml.gz", "rb");
32.59 - if (filelists == NULL)
32.60 - return NULL;
32.61 -
32.62 - ctx.current_parser = ctx.primary_parser;
32.63 -
32.64 - ctx.current = 0;
32.65 -
32.66 - do {
32.67 - XML_GetParsingStatus(ctx.current_parser, &status);
32.68 - switch (status.parsing) {
32.69 - case XML_SUSPENDED:
32.70 - XML_ResumeParser(ctx.current_parser);
32.71 - break;
32.72 - case XML_PARSING:
32.73 - case XML_INITIALIZED:
32.74 - buf = XML_GetBuffer(ctx.current_parser,
32.75 - XML_BUFFER_SIZE);
32.76 - if (ctx.current_parser == ctx.primary_parser)
32.77 - len = gzread(primary, buf, XML_BUFFER_SIZE);
32.78 - else
32.79 - len = gzread(filelists, buf, XML_BUFFER_SIZE);
32.80 - if (len < 0) {
32.81 - fprintf(stderr,
32.82 - "couldn't read input: %s\n",
32.83 - strerror(errno));
32.84 - return NULL;
32.85 - }
32.86 -
32.87 - XML_ParseBuffer(ctx.current_parser, len, len == 0);
32.88 - break;
32.89 - case XML_FINISHED:
32.90 - break;
32.91 + struct yum_context ctx;
32.92 + gchar *s;
32.93 + void *buf;
32.94 + int len;
32.95 + gzFile primary, filelists;
32.96 + XML_ParsingStatus status;
32.97 + struct razor_set *set;
32.98 + int errnum;
32.99 + const char *errstr,*errobj;
32.100 + ctx.importer=razor_importer_create();
32.101 + ctx.state=YUM_STATE_BEGIN;
32.102 + ctx.primary_parser=XML_ParserCreate(NULL);
32.103 + XML_SetUserData(ctx.primary_parser,&ctx);
32.104 + XML_SetElementHandler(ctx.primary_parser,yum_primary_start_element,
32.105 + yum_primary_end_element);
32.106 + XML_SetCharacterDataHandler(ctx.primary_parser,yum_character_data);
32.107 + ctx.filelists_parser=XML_ParserCreate(NULL);
32.108 + XML_SetUserData(ctx.filelists_parser,&ctx);
32.109 + XML_SetElementHandler(ctx.filelists_parser,yum_filelists_start_element,
32.110 + yum_filelists_end_element);
32.111 + XML_SetCharacterDataHandler(ctx.filelists_parser,yum_character_data);
32.112 + errno=0;
32.113 + s=g_build_filename(base,"repodata","primary.xml.gz",NULL);
32.114 + primary=gzopen(s,"rb");
32.115 + if (!primary)
32.116 + {
32.117 + g_set_error(error,RAZOR_POSIX_ERROR,errno?errno:ENOMEM,
32.118 + "%s: %s",s,strerror(errno));
32.119 + g_free(s);
32.120 + return NULL;
32.121 + }
32.122 + g_free(s);
32.123 + s=g_build_filename(base,"repodata","filelists.xml.gz",NULL);
32.124 + filelists=gzopen(s,"rb");
32.125 + if (!filelists)
32.126 + {
32.127 + g_set_error(error,RAZOR_POSIX_ERROR,errno?errno:ENOMEM,
32.128 + "%s: %s",s,strerror(errno));
32.129 + g_free(s);
32.130 + return NULL;
32.131 + }
32.132 + g_free(s);
32.133 + ctx.current_parser=ctx.primary_parser;
32.134 + ctx.current=0;
32.135 + do
32.136 + {
32.137 + XML_GetParsingStatus(ctx.current_parser,&status);
32.138 + switch (status.parsing)
32.139 + {
32.140 + case XML_SUSPENDED:
32.141 + XML_ResumeParser(ctx.current_parser);
32.142 + break;
32.143 + case XML_PARSING:
32.144 + case XML_INITIALIZED:
32.145 + buf=XML_GetBuffer(ctx.current_parser,XML_BUFFER_SIZE);
32.146 + if (ctx.current_parser==ctx.primary_parser)
32.147 + len=gzread(primary,buf,XML_BUFFER_SIZE);
32.148 + else
32.149 + len=gzread(filelists,buf,XML_BUFFER_SIZE);
32.150 + if (len<0)
32.151 + {
32.152 + if (ctx.current_parser==ctx.primary_parser)
32.153 + {
32.154 + errstr=gzerror(primary,&errnum);
32.155 + errobj="primary.xml.gz";
32.156 + }
32.157 + else
32.158 + {
32.159 + errstr=gzerror(filelists,&errnum);
32.160 + errobj="filelists.xml.gz";
32.161 + }
32.162 + if (errnum==Z_ERRNO)
32.163 + g_set_error(error,PLOVER_POSIX_ERROR,errno,"%s: %s",
32.164 + errobj,strerror(errno));
32.165 + else
32.166 + g_set_error(error,RAZOR_ZLIB_ERROR,errnum,"%s: %s",
32.167 + errobj,errstr);
32.168 + return NULL;
32.169 }
32.170 - } while (status.parsing != XML_FINISHED);
32.171 -
32.172 -
32.173 - XML_ParserFree(ctx.primary_parser);
32.174 - XML_ParserFree(ctx.filelists_parser);
32.175 -
32.176 - gzclose(primary);
32.177 - gzclose(filelists);
32.178 -
32.179 - set = razor_importer_finish(ctx.importer);
32.180 -#if RAZOR_HEADER_VERSION_MIN <= 1
32.181 - /*
32.182 - * Header version 1 is supported by plover v0.3 and is used on
32.183 - * 32-bit intel machines which allows the setup and update
32.184 - * applications from v0.3 to work. On other machines, we don't
32.185 - * want these old applications to work (since they would do
32.186 - * the wrong thing) and so we use the current header version
32.187 - * which they don't support.
32.188 - */
32.189 - if (plover_system_arch_is_x86())
32.190 - razor_set_set_header_version(set, 1);
32.191 + XML_ParseBuffer(ctx.current_parser,len,!len);
32.192 + break;
32.193 + case XML_FINISHED:
32.194 + break;
32.195 + }
32.196 + } while (status.parsing!=XML_FINISHED);
32.197 + XML_ParserFree(ctx.primary_parser);
32.198 + XML_ParserFree(ctx.filelists_parser);
32.199 + gzclose(primary);
32.200 + gzclose(filelists);
32.201 + set=razor_importer_finish(ctx.importer);
32.202 +#if RAZOR_HEADER_VERSION_MIN<=1
32.203 + /*
32.204 + * Header version 1 is supported by plover v0.3 and is used on
32.205 + * 32-bit intel machines which allows the setup and update
32.206 + * applications from v0.3 to work. On other machines, we don't
32.207 + * want these old applications to work (since they would do
32.208 + * the wrong thing) and so we use the current header version
32.209 + * which they don't support.
32.210 + */
32.211 + if (plover_system_arch_is_x86())
32.212 + razor_set_set_header_version(set,1);
32.213 #endif
32.214 -
32.215 - return set;
32.216 + return set;
32.217 }
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/plover/log.c Sat Nov 15 19:04:45 2014 +0000
33.3 @@ -0,0 +1,378 @@
33.4 +/*
33.5 + * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
33.6 + *
33.7 + * This program is free software; you can redistribute it and/or modify
33.8 + * it under the terms of the GNU General Public License as published by
33.9 + * the Free Software Foundation; either version 2 of the License, or
33.10 + * (at your option) any later version.
33.11 + *
33.12 + * This program is distributed in the hope that it will be useful,
33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33.15 + * GNU General Public License for more details.
33.16 + *
33.17 + * You should have received a copy of the GNU General Public License along
33.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
33.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33.20 + */
33.21 +
33.22 +#include <stdlib.h>
33.23 +#include <stddef.h>
33.24 +#include <stdio.h>
33.25 +#include <string.h>
33.26 +#include <sys/types.h>
33.27 +#include <sys/stat.h>
33.28 +#include <unistd.h>
33.29 +#include <time.h>
33.30 +#include <errno.h>
33.31 +#include <fcntl.h>
33.32 +#ifdef WIN32
33.33 +#include <windows.h>
33.34 +#include <io.h>
33.35 +#else
33.36 +#include <dirent.h>
33.37 +#endif
33.38 +#include "config.h"
33.39 +#include "plover.h"
33.40 +
33.41 +#ifndef FALSE
33.42 +#define FALSE 0
33.43 +#endif
33.44 +
33.45 +#ifndef TRUE
33.46 +#define TRUE (!FALSE)
33.47 +#endif
33.48 +
33.49 +#define MAX_OLD_LOGFILES 4 /* (5 including the current) */
33.50 +
33.51 +#ifdef WIN32
33.52 +
33.53 +struct find_suffixed_data {
33.54 + HANDLE handle;
33.55 + WIN32_FIND_DATA wfd;
33.56 + int base_len;
33.57 + char *suffix;
33.58 +};
33.59 +
33.60 +static int find_suffixed_first(const char *path,struct find_suffixed_data *data)
33.61 +{
33.62 + const char *t1,*t2;
33.63 + gchar *s;
33.64 + s=g_strconcat(path,"-*",NULL);
33.65 + data->handle=FindFirstFile(s,&data->wfd);
33.66 + g_free(s);
33.67 + if (data->handle==INVALID_HANDLE_VALUE)
33.68 + return FALSE;
33.69 + t1=strrchr(path,'/');
33.70 + t2=strrchr(t1?t1:path,'\\');
33.71 + if (t2)
33.72 + data->base_len=strlen(t2+1);
33.73 + else if (t1)
33.74 + data->base_len=strlen(t1+1);
33.75 + else
33.76 + data->base_len=strlen(path);
33.77 + data->suffix=strdup(data->wfd.cFileName+data->base_len);
33.78 + return TRUE;
33.79 +}
33.80 +
33.81 +static int find_suffixed_next(struct find_suffixed_data *data)
33.82 +{
33.83 + if (!FindNextFile(data->handle,&data->wfd))
33.84 + return FALSE;
33.85 + free(data->suffix);
33.86 + data->suffix=strdup(data->wfd.cFileName+data->base_len);
33.87 + return TRUE;
33.88 +}
33.89 +
33.90 +static void find_suffixed_close(struct find_suffixed_data *data)
33.91 +{
33.92 + free(data->suffix);
33.93 + FindClose(data->handle);
33.94 +}
33.95 +
33.96 +#else /* WIN32 */
33.97 +
33.98 +struct find_suffixed_data {
33.99 + DIR *dir;
33.100 + struct dirent *entry;
33.101 + char *base;
33.102 + int base_len;
33.103 + char *suffix;
33.104 +};
33.105 +
33.106 +static int find_suffixed_next(struct find_suffixed_data *data)
33.107 +{
33.108 + struct dirent *entry_result;
33.109 + while (!readdir_r(data->dir,data->entry,&entry_result) && entry_result)
33.110 + {
33.111 + if (strncmp(data->entry->d_name,data->base,data->base_len) ||
33.112 + data->entry->d_name[data->base_len]!='-')
33.113 + continue;
33.114 + free(data->suffix);
33.115 + data->suffix=strdup(data->entry->d_name+data->base_len);
33.116 + return TRUE;
33.117 + }
33.118 + return FALSE;
33.119 +}
33.120 +
33.121 +/*
33.122 + * From http://womble.decadent.org.uk/readdir_r-advisory.html
33.123 + *
33.124 + * Calculate the required buffer size (in bytes) for directory
33.125 + * entries read from the given directory handle. Return -1 if this
33.126 + * this cannot be done.
33.127 + *
33.128 + * This code does not trust values of NAME_MAX that are less than
33.129 + * 255, since some systems (including at least HP-UX) incorrectly
33.130 + * define it to be a smaller value.
33.131 + *
33.132 + * If you use autoconf, include fpathconf and dirfd in your
33.133 + * AC_CHECK_FUNCS list. Otherwise use some other method to detect
33.134 + * and use them where available.
33.135 + */
33.136 +
33.137 +static size_t dirent_buf_size(DIR * dirp)
33.138 +{
33.139 + long name_max;
33.140 + size_t name_end;
33.141 +#if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) && defined(_PC_NAME_MAX)
33.142 + name_max=fpathconf(dirfd(dirp),_PC_NAME_MAX);
33.143 + if (name_max==-1)
33.144 +#if defined(NAME_MAX)
33.145 + name_max=(NAME_MAX>255)?NAME_MAX:255;
33.146 +#else
33.147 + return (size_t)-1;
33.148 +#endif /* NAME_MAX */
33.149 +#else
33.150 +#if defined(NAME_MAX)
33.151 + name_max=(NAME_MAX>255)?NAME_MAX:255;
33.152 +#else
33.153 +#error "buffer size for readdir_r cannot be determined"
33.154 +#endif /* NAME_MAX */
33.155 +#endif /* HAVE_FPATHCONF && HAVE_DIRFD && _PC_NAME_MAX */
33.156 + name_end=(size_t)offsetof(struct dirent,d_name)+name_max+1;
33.157 + return (name_end>sizeof(struct dirent)?name_end:sizeof(struct dirent));
33.158 +}
33.159 +
33.160 +static int find_suffixed_first(const char *path,struct find_suffixed_data *data)
33.161 +{
33.162 + int len;
33.163 + char *s,*base;
33.164 + base=strrchr(path,'/');
33.165 + if (base)
33.166 + {
33.167 + if (base==path)
33.168 + data->dir=opendir("/");
33.169 + else
33.170 + {
33.171 + s=strndup(path,base-path);
33.172 + data->dir=opendir(s);
33.173 + free(s);
33.174 + }
33.175 + data->base=strdup(path+1);
33.176 + }
33.177 + else
33.178 + {
33.179 + data->dir=opendir(".");
33.180 + data->base=strdup(path);
33.181 + }
33.182 + if (!data->dir)
33.183 + {
33.184 + free(data->base);
33.185 + return FALSE;
33.186 + }
33.187 + data->base_len=strlen(data->base);
33.188 + len=dirent_buf_size(data->dir);
33.189 + if (len<0)
33.190 + {
33.191 + closedir(data->dir);
33.192 + return FALSE;
33.193 + }
33.194 + data->entry=malloc(len);
33.195 + if (!data->entry)
33.196 + {
33.197 + closedir(data->dir);
33.198 + return FALSE;
33.199 + }
33.200 + if (find_suffixed_next(data))
33.201 + return TRUE;
33.202 + free(data->entry);
33.203 + closedir(data->dir);
33.204 + return FALSE;
33.205 +}
33.206 +
33.207 +static void find_suffixed_close(struct find_suffixed_data *data)
33.208 +{
33.209 + free(data->suffix);
33.210 + free(data->entry);
33.211 + closedir(data->dir);
33.212 +}
33.213 +
33.214 +#endif /* WIN32 */
33.215 +
33.216 +static int prune_old_logfiles(const char *path)
33.217 +{
33.218 + int i,n_suffixes;
33.219 + gchar *s;
33.220 + char *suffix,*suffixes[MAX_OLD_LOGFILES];
33.221 + struct find_suffixed_data fsd;
33.222 + if (find_suffixed_first(path,&fsd))
33.223 + {
33.224 + n_suffixes=0;
33.225 + do
33.226 + {
33.227 + suffix=strdup(fsd.suffix);
33.228 + if (n_suffixes<MAX_OLD_LOGFILES)
33.229 + suffixes[n_suffixes++]=suffix;
33.230 + else
33.231 + {
33.232 + for(i=0;i<MAX_OLD_LOGFILES;i++)
33.233 + if (strcmp(suffix,suffixes[i])>0)
33.234 + {
33.235 + s=suffixes[i];
33.236 + suffixes[i]=suffix;
33.237 + suffix=s;
33.238 + }
33.239 + s=g_strconcat(path,suffix,NULL);
33.240 + (void)remove(s);
33.241 + g_free(s);
33.242 + free(suffix);
33.243 + }
33.244 + } while(find_suffixed_next(&fsd));
33.245 + find_suffixed_close(&fsd);
33.246 + for(i=0;i<n_suffixes;i++)
33.247 + free(suffixes[i]);
33.248 + }
33.249 + return 0;
33.250 +}
33.251 +
33.252 +static int rotate_logfile(const char *path,struct tm *modified)
33.253 +{
33.254 + gchar *s;
33.255 + char serial;
33.256 + char suffix[11]; /* -yyyymmdd or -yyyymmdds */
33.257 + sprintf(suffix,"-%04d%02d%02d",modified->tm_year+1900,modified->tm_mon+1,
33.258 + modified->tm_mday);
33.259 + s=g_strconcat(path,suffix,NULL);
33.260 + if (rename(path,s))
33.261 + {
33.262 + suffix[10]='\0';
33.263 + for(serial='a';serial<='z';serial++)
33.264 + {
33.265 + if (errno!=EACCES || serial=='z')
33.266 + {
33.267 + perror(s);
33.268 + free(s);
33.269 + return -1;
33.270 + }
33.271 + free(s);
33.272 + suffix[9]=serial;
33.273 + s=g_strconcat(path,suffix,NULL);
33.274 + if (!rename(path,s))
33.275 + break;
33.276 + }
33.277 + }
33.278 + g_free(s);
33.279 + return prune_old_logfiles(path);
33.280 +}
33.281 +
33.282 +int plover_log_open(const char *path)
33.283 +{
33.284 + int retval;
33.285 + char *root;
33.286 + gchar *filename;
33.287 + struct stat sb;
33.288 + time_t t;
33.289 + struct tm today,modified;
33.290 + struct razor_atomic *atomic;
33.291 + FILE *fp;
33.292 + root=getenv("RAZOR_ROOT");
33.293 + if (root)
33.294 + filename=g_strconcat(root,path,NULL);
33.295 + else
33.296 + filename=g_strdup(path);
33.297 + atomic=razor_atomic_open("Open log");
33.298 + razor_atomic_make_dirs(atomic,"",filename);
33.299 + retval=razor_atomic_commit(atomic);
33.300 + if (retval)
33.301 + fprintf(stderr,"Can't open log: %s\n",
33.302 + razor_atomic_get_error_msg(atomic));
33.303 + razor_atomic_destroy(atomic);
33.304 + if (retval)
33.305 + return retval;
33.306 + if (stat(filename,&sb)<0)
33.307 + {
33.308 + if (errno!=ENOENT)
33.309 + {
33.310 + fprintf(stderr,"Can't open log: ");
33.311 + perror(filename);
33.312 + g_free(filename);
33.313 + return -1;
33.314 + }
33.315 + }
33.316 + else if (!S_ISREG(sb.st_mode))
33.317 + {
33.318 + fprintf(stderr,"Can't open log: %s: Not a regular file\n",filename);
33.319 + g_free(filename);
33.320 + return -1;
33.321 + }
33.322 + else
33.323 + {
33.324 + time(&t);
33.325 +#ifdef WIN32
33.326 + localtime_s(&today,&t);
33.327 + localtime_s(&modified,&sb.st_mtime);
33.328 +#else
33.329 + localtime_r(&t,&today);
33.330 + localtime_r(&sb.st_mtime,&modified);
33.331 +#endif
33.332 + if (modified.tm_yday!=today.tm_yday || modified.tm_year!=today.tm_year)
33.333 + rotate_logfile(filename,&modified);
33.334 + }
33.335 + fp=fopen(filename,"a");
33.336 + if (!fp)
33.337 + {
33.338 + fprintf(stderr,"Can't open log: ");
33.339 + perror(filename);
33.340 + g_free(filename);
33.341 + return -1;
33.342 + }
33.343 + g_free(filename);
33.344 +#ifdef WIN32
33.345 + /*
33.346 + * The situation under MS-Windows is a little complicated. If standard
33.347 + * output and standard error are valid then the normal code will work.
33.348 + * This applies in console applications and even in GUI applications
33.349 + * if standard output and standard error are redirected by the parent
33.350 + * process (eg., by cmd.exe). However GUI applications started in
33.351 + * typical fashion will have invalid standard output and standard error.
33.352 + * See http://support.microsoft.com/kb/105305 for some more detail.
33.353 + * NB: This solution assumes that fd 1 and 2 are either used for
33.354 + * standard output/error or are unused.
33.355 + */
33.356 + fclose(stdout);
33.357 + fclose(stderr);
33.358 +#else
33.359 + fflush(stdout);
33.360 + fflush(stderr);
33.361 +#endif
33.362 + if (dup2(fileno(fp),1)<0 || dup2(fileno(fp),2)<0)
33.363 + {
33.364 + perror("Failed to redirect standard error/output");
33.365 + fclose(fp);
33.366 + return -1;
33.367 + }
33.368 + fclose(fp);
33.369 +#ifdef WIN32
33.370 + *stdout=*fdopen(1,"a");
33.371 + setvbuf(stdout,NULL,_IONBF,0);
33.372 + *stderr=*fdopen(2,"a");
33.373 + setvbuf(stderr,NULL,_IONBF,0);
33.374 + SetStdHandle(STD_OUTPUT_HANDLE,(HANDLE)_get_osfhandle(1));
33.375 + SetStdHandle(STD_ERROR_HANDLE,(HANDLE)_get_osfhandle(2));
33.376 +#endif
33.377 + time(&t);
33.378 + printf("Run started on %s",ctime(&t));
33.379 + fflush(stdout);
33.380 + return 0;
33.381 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/plover/package.c Sat Nov 15 19:04:45 2014 +0000
34.3 @@ -0,0 +1,274 @@
34.4 +/*
34.5 + * Copyright (C) 2010 J. Ali Harlow <ali@juiblex.co.uk>
34.6 + *
34.7 + * This program is free software; you can redistribute it and/or modify
34.8 + * it under the terms of the GNU General Public License as published by
34.9 + * the Free Software Foundation; either version 2 of the License, or
34.10 + * (at your option) any later version.
34.11 + *
34.12 + * This program is distributed in the hope that it will be useful,
34.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
34.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34.15 + * GNU General Public License for more details.
34.16 + *
34.17 + * You should have received a copy of the GNU General Public License along
34.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
34.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34.20 + */
34.21 +
34.22 +#include "config.h"
34.23 +#include <stdlib.h>
34.24 +#include <string.h>
34.25 +#include <glib-object.h>
34.26 +#include <razor.h>
34.27 +#include "plover/package.h"
34.28 +
34.29 +G_DEFINE_TYPE(PloverPackage,plover_package,G_TYPE_OBJECT);
34.30 +
34.31 +typedef struct _PloverPackagePrivate {
34.32 + struct razor_set *set;
34.33 + struct razor_package *pkg;
34.34 + GObject *file_store;
34.35 + const char **prefixes;
34.36 +} PloverPackagePrivate;
34.37 +
34.38 +#define PLOVER_PACKAGE_GET_PRIVATE(obj)\
34.39 + G_TYPE_INSTANCE_GET_PRIVATE(obj,\
34.40 + PLOVER_TYPE_PACKAGE,PloverPackagePrivate)
34.41 +
34.42 +enum {
34.43 + CHANGED=0,
34.44 + N_SIGNALS
34.45 +};
34.46 +
34.47 +static guint signals[N_SIGNALS];
34.48 +
34.49 +static void plover_package_finalize(GObject *obj)
34.50 +{
34.51 + PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj);
34.52 + g_free(priv->prefixes);
34.53 + G_OBJECT_CLASS(plover_package_parent_class)->finalize(obj);
34.54 +}
34.55 +
34.56 +static void plover_package_dispose(GObject *obj)
34.57 +{
34.58 + PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj);
34.59 + if (priv->file_store)
34.60 + {
34.61 + g_object_unref(priv->file_store);
34.62 + priv->file_store=NULL;
34.63 + }
34.64 + G_OBJECT_CLASS(plover_package_parent_class)->dispose(obj);
34.65 +}
34.66 +
34.67 +static void plover_package_class_init(PloverPackageClass *klass)
34.68 +{
34.69 + GObjectClass *oclass=G_OBJECT_CLASS(klass);
34.70 + oclass->finalize=plover_package_finalize;
34.71 + oclass->dispose=plover_package_dispose;
34.72 + g_type_class_add_private(klass,sizeof(PloverPackagePrivate));
34.73 + signals[CHANGED]=g_signal_newv("changed",
34.74 + G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
34.75 + g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
34.76 +}
34.77 +
34.78 +static void plover_package_init(PloverPackage *package)
34.79 +{
34.80 +}
34.81 +
34.82 +PloverPackage *plover_package_new(struct razor_set *set,
34.83 + struct razor_package *pkg)
34.84 +{
34.85 + PloverPackage *package;
34.86 + PloverPackagePrivate *priv;
34.87 + package=g_object_new(PLOVER_TYPE_PACKAGE,NULL);
34.88 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.89 + priv->set=set;
34.90 + priv->pkg=pkg;
34.91 + return package;
34.92 +}
34.93 +
34.94 +struct razor_set *plover_package_get_razor_set(PloverPackage *package)
34.95 +{
34.96 + PloverPackagePrivate *priv;
34.97 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.98 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.99 + return priv->set;
34.100 +}
34.101 +
34.102 +struct razor_package *plover_package_get_razor_package(PloverPackage *package)
34.103 +{
34.104 + PloverPackagePrivate *priv;
34.105 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.106 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.107 + return priv->pkg;
34.108 +}
34.109 +
34.110 +const char *plover_package_get_name(PloverPackage *package)
34.111 +{
34.112 + PloverPackagePrivate *priv;
34.113 + const char *name=NULL;
34.114 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.115 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.116 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_NAME,&name,
34.117 + RAZOR_DETAIL_LAST);
34.118 + return name;
34.119 +}
34.120 +
34.121 +const char *plover_package_get_summary(PloverPackage *package)
34.122 +{
34.123 + PloverPackagePrivate *priv;
34.124 + const char *summary=NULL;
34.125 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.126 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.127 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_SUMMARY,&summary,
34.128 + RAZOR_DETAIL_LAST);
34.129 + return summary;
34.130 +}
34.131 +
34.132 +const char *plover_package_get_version(PloverPackage *package)
34.133 +{
34.134 + PloverPackagePrivate *priv;
34.135 + const char *version=NULL;
34.136 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.137 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.138 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_VERSION,&version,
34.139 + RAZOR_DETAIL_LAST);
34.140 + return version;
34.141 +}
34.142 +
34.143 +const char *plover_package_get_license(PloverPackage *package)
34.144 +{
34.145 + PloverPackagePrivate *priv;
34.146 + const char *license=NULL;
34.147 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.148 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.149 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_LICENSE,&license,
34.150 + RAZOR_DETAIL_LAST);
34.151 + return license;
34.152 +}
34.153 +
34.154 +const char *plover_package_get_arch(PloverPackage *package)
34.155 +{
34.156 + PloverPackagePrivate *priv;
34.157 + const char *arch=NULL;
34.158 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.159 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.160 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_ARCH,&arch,
34.161 + RAZOR_DETAIL_LAST);
34.162 + return arch;
34.163 +}
34.164 +
34.165 +const char *plover_package_get_description(PloverPackage *package)
34.166 +{
34.167 + PloverPackagePrivate *priv;
34.168 + const char *description=NULL;
34.169 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.170 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.171 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_DESCRIPTION,
34.172 + &description,RAZOR_DETAIL_LAST);
34.173 + return description;
34.174 +}
34.175 +
34.176 +const char *plover_package_get_URL(PloverPackage *package)
34.177 +{
34.178 + PloverPackagePrivate *priv;
34.179 + const char *URL=NULL;
34.180 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.181 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.182 + razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_URL,&URL,
34.183 + RAZOR_DETAIL_LAST);
34.184 + return URL;
34.185 +}
34.186 +
34.187 +/**
34.188 + * plover_package_read_icon:
34.189 + * @package: #PloverPackage to read icon from
34.190 + * @error: a #GError, or %NULL
34.191 + *
34.192 + * Opens an icon for reading. The result is a #GInputStream that
34.193 + * can be used to read the contents of the file.
34.194 + *
34.195 + * If the icon does not exist, the %G_IO_ERROR_NOT_FOUND error will be
34.196 + * returned. Other errors are possible too.
34.197 + *
34.198 + * Returns: (transfer full): #GInputStream or %NULL on error.
34.199 + * Free the returned object with g_object_unref().
34.200 + */
34.201 +GInputStream *plover_package_read_icon(PloverPackage *package,GError **error)
34.202 +{
34.203 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.204 + g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_NOT_SUPPORTED,
34.205 + "Operation not supported");
34.206 + return NULL;
34.207 +}
34.208 +
34.209 +/**
34.210 + * plover_package_property_iterator_create:
34.211 + * @package: #PloverPackage to create property iterator for
34.212 + *
34.213 + * Creates a property iterator for package. The result is a
34.214 + * #struct razor_property_iterator that can be used to iterate over the
34.215 + * properties of a package.
34.216 + *
34.217 + * Returns: (transfer full): #struct razor_property_iterator or %NULL on error.
34.218 + * Free the returned iterator with razor_property_iterator_destroy().
34.219 + */
34.220 +struct razor_property_iterator *
34.221 + plover_package_property_iterator_create(PloverPackage *package)
34.222 +{
34.223 + PloverPackagePrivate *priv;
34.224 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.225 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.226 + return razor_property_iterator_create(priv->set,priv->pkg);
34.227 +}
34.228 +
34.229 +/**
34.230 + * plover_package_file_iterator_create:
34.231 + * @package: #PloverPackage to create file iterator for
34.232 + * @reverse: %TRUE if the files should be iterated in reverse order
34.233 + *
34.234 + * Creates a file iterator for package. The result is a
34.235 + * #struct razor_file_iterator that can be used to iterate over the files
34.236 + * in a package.
34.237 + *
34.238 + * Returns: (transfer full): #struct razor_file_iterator or %NULL on error.
34.239 + * Free the returned iterator with razor_file_iterator_destroy().
34.240 + */
34.241 +struct razor_file_iterator *
34.242 + plover_package_file_iterator_create(PloverPackage *package,gboolean reverse)
34.243 +{
34.244 + PloverPackagePrivate *priv;
34.245 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.246 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.247 + return razor_file_iterator_create(priv->set,priv->pkg,reverse);
34.248 +}
34.249 +
34.250 +/**
34.251 + * plover_package_get_prefixes:
34.252 + * @package: #PloverPackage to get prefixes for
34.253 + *
34.254 + * Retrieve the prefixes for a relocatable package.
34.255 + *
34.256 + * Returns: (transfer none): NULL-terminated array of prefixes.
34.257 + */
34.258 +const char *const *plover_package_get_prefixes(PloverPackage *package)
34.259 +{
34.260 + const char *prefix;
34.261 + struct razor_string_iterator *si;
34.262 + GPtrArray *prefixes;
34.263 + PloverPackagePrivate *priv;
34.264 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
34.265 + priv=PLOVER_PACKAGE_GET_PRIVATE(package);
34.266 + if (!priv->prefixes)
34.267 + {
34.268 + prefixes=g_ptr_array_new();
34.269 + si=razor_install_prefix_iterator_create(priv->set,priv->pkg);
34.270 + while (razor_string_iterator_next(si,&prefix))
34.271 + g_ptr_array_add(prefixes,prefix);
34.272 + razor_string_iterator_destroy(si);
34.273 + g_ptr_array_add(prefixes,NULL);
34.274 + priv->prefixes=g_ptr_array_free(prefixes,FALSE);
34.275 + }
34.276 + return priv->prefixes;
34.277 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/plover/package.h Sat Nov 15 19:04:45 2014 +0000
35.3 @@ -0,0 +1,56 @@
35.4 +#ifndef __PLOVER_PACKAGE_H__
35.5 +#define __PLOVER_PACKAGE_H__
35.6 +
35.7 +#include <razor.h>
35.8 +#include <glib-object.h>
35.9 +#include <gio/gio.h>
35.10 +
35.11 +G_BEGIN_DECLS
35.12 +
35.13 +#define PLOVER_TYPE_PACKAGE plover_package_get_type()
35.14 +#define PLOVER_PACKAGE(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
35.15 + PLOVER_TYPE_PACKAGE,PloverPackage)
35.16 +#define PLOVER_PACKAGE_CLASS(klass)\
35.17 + G_TYPE_CHECK_CLASS_CAST(klass,\
35.18 + PLOVER_TYPE_PACKAGE,PloverPackageClass)
35.19 +#define PLOVER_IS_PACKAGE(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj,\
35.20 + PLOVER_TYPE_PACKAGE)
35.21 +#define PLOVER_IS_PACKAGE_CLASS(klass)\
35.22 + G_TYPE_CHECK_CLASS_TYPE(obj,\
35.23 + PLOVER_TYPE_PACKAGE)
35.24 +#define PLOVER_PACKAGE_GET_CLASS(obj)\
35.25 + G_TYPE_INSTANCE_GET_CLASS(obj,\
35.26 + PLOVER_TYPE_PACKAGE,PloverPackageClass)
35.27 +
35.28 +typedef struct _PloverPackage {
35.29 + GObject parent_instance;
35.30 +} PloverPackage;
35.31 +
35.32 +typedef struct _PloverPackageClass {
35.33 + GObjectClass parent_class;
35.34 +} PloverPackageClass;
35.35 +
35.36 +#include <plover/packageset.h>
35.37 +
35.38 +GType plover_package_get_type(void) G_GNUC_CONST;
35.39 +PloverPackage *plover_package_new(struct razor_set *set,
35.40 + struct razor_package *pkg);
35.41 +struct razor_set *plover_package_get_razor_set(PloverPackage *package);
35.42 +struct razor_package *plover_package_get_razor_package(PloverPackage *package);
35.43 +const char *plover_package_get_name(PloverPackage *package);
35.44 +const char *plover_package_get_summary(PloverPackage *package);
35.45 +const char *plover_package_get_version(PloverPackage *package);
35.46 +const char *plover_package_get_license(PloverPackage *package);
35.47 +const char *plover_package_get_arch(PloverPackage *package);
35.48 +const char *plover_package_get_description(PloverPackage *package);
35.49 +const char *plover_package_get_URL(PloverPackage *package);
35.50 +GInputStream *plover_package_get_icon_stream(PloverPackage *package);
35.51 +struct razor_property_iterator *
35.52 + plover_package_property_iterator_create(PloverPackage *package);
35.53 +struct razor_file_iterator *
35.54 + plover_package_file_iterator_create(PloverPackage *package,gboolean reverse);
35.55 +const char *const *plover_package_get_prefixes(PloverPackage *package);
35.56 +
35.57 +G_END_DECLS
35.58 +
35.59 +#endif /* __PLOVER_PACKAGE_H__ */
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/plover/packageset.c Sat Nov 15 19:04:45 2014 +0000
36.3 @@ -0,0 +1,658 @@
36.4 +/*
36.5 + * Copyright (C) 2010-2012, 2014 J. Ali Harlow <ali@juiblex.co.uk>
36.6 + *
36.7 + * This program is free software; you can redistribute it and/or modify
36.8 + * it under the terms of the GNU General Public License as published by
36.9 + * the Free Software Foundation; either version 2 of the License, or
36.10 + * (at your option) any later version.
36.11 + *
36.12 + * This program is distributed in the hope that it will be useful,
36.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
36.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36.15 + * GNU General Public License for more details.
36.16 + *
36.17 + * You should have received a copy of the GNU General Public License along
36.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
36.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36.20 + */
36.21 +
36.22 +#include "config.h"
36.23 +#include <stdlib.h>
36.24 +#include <string.h>
36.25 +#include <fcntl.h>
36.26 +#include <errno.h>
36.27 +#include <unistd.h>
36.28 +#include <glib-object.h>
36.29 +#include <razor.h>
36.30 +#include "plover/plover.h"
36.31 +#include "plover/package.h"
36.32 +#include "plover/packageset.h"
36.33 +
36.34 +G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT);
36.35 +
36.36 +typedef struct _PloverPackageSetPrivate {
36.37 + gchar *install_root;
36.38 + struct razor_root *root;
36.39 + struct razor_set *set;
36.40 + GSList *packages;
36.41 + int no_details;
36.42 + gchar *guessed_prefix;
36.43 +} PloverPackageSetPrivate;
36.44 +
36.45 +#define PLOVER_PACKAGE_SET_GET_PRIVATE(obj)\
36.46 + G_TYPE_INSTANCE_GET_PRIVATE(obj,\
36.47 + PLOVER_TYPE_PACKAGE_SET,\
36.48 + PloverPackageSetPrivate)
36.49 +
36.50 +enum {
36.51 + CHANGED=0,
36.52 + N_SIGNALS
36.53 +};
36.54 +
36.55 +static guint signals[N_SIGNALS];
36.56 +
36.57 +static void plover_package_set_finalize(GObject *obj)
36.58 +{
36.59 + PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
36.60 + g_free(priv->guessed_prefix);
36.61 + G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj);
36.62 +}
36.63 +
36.64 +static void plover_package_set_dispose(GObject *obj)
36.65 +{
36.66 + PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
36.67 + if (priv->set)
36.68 + {
36.69 + razor_set_unref(priv->set);
36.70 + priv->set=NULL;
36.71 + }
36.72 + if (priv->root)
36.73 + {
36.74 + g_free(priv->install_root);
36.75 + priv->install_root=NULL;
36.76 + razor_root_close(priv->root);
36.77 + priv->root=NULL;
36.78 + }
36.79 + G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj);
36.80 +}
36.81 +
36.82 +static void plover_package_set_class_init(PloverPackageSetClass *klass)
36.83 +{
36.84 + GObjectClass *oclass=G_OBJECT_CLASS(klass);
36.85 + oclass->finalize=plover_package_set_finalize;
36.86 + oclass->dispose=plover_package_set_dispose;
36.87 + g_type_class_add_private(klass,sizeof(PloverPackageSetPrivate));
36.88 + signals[CHANGED]=g_signal_newv("changed",
36.89 + G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
36.90 + g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
36.91 +}
36.92 +
36.93 +static void plover_package_set_init(PloverPackageSet *set)
36.94 +{
36.95 + PloverPackageSetPrivate *priv;
36.96 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.97 + priv->no_details=-1;
36.98 +}
36.99 +
36.100 +PloverPackageSet *plover_package_set_new(void)
36.101 +{
36.102 + return g_object_new(PLOVER_TYPE_PACKAGE_SET,NULL);
36.103 +}
36.104 +
36.105 +void plover_package_set_close(PloverPackageSet *set)
36.106 +{
36.107 + PloverPackageSetPrivate *priv;
36.108 + g_return_if_fail(PLOVER_IS_PACKAGE_SET(set));
36.109 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.110 + if (priv->root)
36.111 + {
36.112 + razor_root_close(priv->root);
36.113 + priv->root=NULL;
36.114 + }
36.115 +}
36.116 +
36.117 +gboolean plover_package_set_open(PloverPackageSet *set,const char *install_root,
36.118 + gboolean exclusive,GError **err)
36.119 +{
36.120 + struct razor_root *root=NULL;
36.121 + struct razor_set *system=NULL;
36.122 + PloverPackageSetPrivate *priv;
36.123 + struct razor_error *error=NULL;
36.124 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
36.125 + if (exclusive)
36.126 + {
36.127 + root=razor_root_open(install_root,NULL);
36.128 + if (!root)
36.129 + {
36.130 + if (razor_root_create(install_root,&error))
36.131 + {
36.132 + if (razor_error_get_domain(error)==RAZOR_GENERAL_ERROR &&
36.133 + razor_error_get_code(error)==
36.134 + RAZOR_GENERAL_ERROR_DATABASE_EXISTS)
36.135 + {
36.136 + razor_error_free(error);
36.137 + error=NULL;
36.138 + root=razor_root_open(install_root,&error);
36.139 + }
36.140 + }
36.141 + else
36.142 + root=razor_root_open(install_root,&error);
36.143 + if (!root)
36.144 + {
36.145 + plover_propagate_razor_error(err,error);
36.146 + return FALSE;
36.147 + }
36.148 + }
36.149 + system=razor_root_get_system_set(root);
36.150 + if (system)
36.151 + razor_set_ref(system);
36.152 + }
36.153 + else
36.154 + system=razor_root_open_read_only(install_root,&error);
36.155 + if (error)
36.156 + {
36.157 + g_set_error_literal(err,PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED,
36.158 + razor_error_get_msg(error));
36.159 + razor_error_free(error);
36.160 + return FALSE;
36.161 + }
36.162 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.163 + if (priv->set)
36.164 + {
36.165 + razor_set_unref(priv->set);
36.166 + priv->set=NULL;
36.167 + }
36.168 + if (priv->root)
36.169 + {
36.170 + razor_root_close(priv->root);
36.171 + priv->root=NULL;
36.172 + }
36.173 + g_free(priv->install_root);
36.174 + priv->install_root=g_strdup(install_root);
36.175 + priv->root=root;
36.176 + priv->set=system;
36.177 + return TRUE;
36.178 +}
36.179 +
36.180 +const char *plover_package_set_get_install_root(PloverPackageSet *set)
36.181 +{
36.182 + PloverPackageSetPrivate *priv;
36.183 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.184 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.185 + return priv->install_root;
36.186 +}
36.187 +
36.188 +gboolean plover_package_set_get_exclusive(PloverPackageSet *set)
36.189 +{
36.190 + PloverPackageSetPrivate *priv;
36.191 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
36.192 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.193 + return !!priv->root;
36.194 +}
36.195 +
36.196 +gboolean plover_package_set_update(PloverPackageSet *set,struct razor_set *next,
36.197 + struct razor_atomic *atomic)
36.198 +{
36.199 + gboolean retval;
36.200 + PloverPackageSetPrivate *priv;
36.201 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
36.202 + g_return_val_if_fail(plover_package_set_get_exclusive(set) != FALSE,FALSE);
36.203 + g_return_val_if_fail(next != NULL,FALSE);
36.204 + g_return_val_if_fail(atomic != NULL,FALSE);
36.205 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.206 + retval=!razor_root_update(priv->root,next,atomic);
36.207 + if (retval)
36.208 + {
36.209 + razor_set_unref(priv->set);
36.210 + priv->set=razor_root_get_system_set(priv->root);
36.211 + if (priv->set)
36.212 + razor_set_ref(priv->set);
36.213 + }
36.214 + return retval;
36.215 +}
36.216 +
36.217 +PloverPackageSet *plover_package_set_new_from_installed(const char *root,
36.218 + GError **err)
36.219 +{
36.220 + PloverPackageSet *set;
36.221 + set=plover_package_set_new();
36.222 + if (!plover_package_set_open(set,root,FALSE,err))
36.223 + {
36.224 + g_object_unref(set);
36.225 + return NULL;
36.226 + }
36.227 + return set;
36.228 +}
36.229 +
36.230 +PloverPackageSet *plover_package_set_new_from_razor(struct razor_set *razor)
36.231 +{
36.232 + PloverPackageSet *set;
36.233 + PloverPackageSetPrivate *priv;
36.234 + g_return_val_if_fail(razor != NULL,NULL);
36.235 + set=plover_package_set_new();
36.236 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.237 + priv->set=razor;
36.238 + razor_set_ref(priv->set);
36.239 + return set;
36.240 +}
36.241 +
36.242 +static gboolean
36.243 + plover_package_set_import_package(PloverRepository *repository,
36.244 + struct razor_relocations *relocations,struct razor_importer *importer,
36.245 + PloverPackage *package,GError **error)
36.246 +{
36.247 + struct razor_property_iterator *prop_iter;
36.248 + struct razor_file_iterator *file_iter;
36.249 + struct razor_rpm *rpm;
36.250 + struct razor_property *prop;
36.251 + const char *name,*version,*arch,*summary,*desc,*url,*license;
36.252 + uint32_t flags;
36.253 + rpm=plover_repository_open_rpm(repository,package,error);
36.254 + if (!rpm)
36.255 + return FALSE;
36.256 + razor_relocations_set_rpm(relocations,rpm);
36.257 + razor_rpm_close(rpm);
36.258 + name=plover_package_get_name(package);
36.259 + version=plover_package_get_version(package);
36.260 + arch=plover_package_get_arch(package);
36.261 + razor_importer_begin_package(importer,name,version,arch);
36.262 + summary=plover_package_get_summary(package);
36.263 + desc=plover_package_get_description(package);
36.264 + url=plover_package_get_URL(package);
36.265 + license=plover_package_get_license(package);
36.266 + razor_importer_add_details(importer,summary,desc,url,license);
36.267 + prop_iter=plover_package_property_iterator_create(package);
36.268 + while (razor_property_iterator_next(prop_iter,&prop,&name,&flags,&version))
36.269 + razor_importer_add_property(importer,name,flags,version);
36.270 + razor_property_iterator_destroy(prop_iter);
36.271 + file_iter=plover_package_file_iterator_create(package,FALSE);
36.272 + while (razor_file_iterator_next(file_iter,&name))
36.273 + {
36.274 + name=razor_relocations_apply(relocations,name);
36.275 + razor_importer_add_file(importer,name);
36.276 + }
36.277 + razor_file_iterator_destroy(file_iter);
36.278 + razor_importer_finish_package(importer);
36.279 + return TRUE;
36.280 +}
36.281 +
36.282 +PloverPackageSet *
36.283 + plover_package_set_new_from_repository(PloverRepository *repository,
36.284 + struct razor_relocations *relocations,GError **error)
36.285 +{
36.286 + struct razor_importer *importer;
36.287 + uint32_t header_version;
36.288 + GSList *packages,*lnk;
36.289 + PloverPackageSet *unrelocated,*set;
36.290 + PloverPackageSetPrivate *priv;
36.291 + PloverPackage *package;
36.292 + g_return_val_if_fail(PLOVER_IS_REPOSITORY(repository),NULL);
36.293 + unrelocated=plover_repository_get_package_set(repository);
36.294 + set=plover_package_set_new();
36.295 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.296 + if (relocations)
36.297 + {
36.298 + importer=razor_importer_create();
36.299 + packages=plover_package_set_get_packages(unrelocated);
36.300 + for(lnk=packages;lnk;lnk=lnk->next)
36.301 + {
36.302 + package=lnk->data;
36.303 + if (!plover_package_set_import_package(repository,relocations,
36.304 + importer,package,error))
36.305 + {
36.306 + razor_importer_destroy(importer);
36.307 + g_object_unref(set);
36.308 + return NULL;
36.309 + }
36.310 + }
36.311 + priv->set=razor_importer_finish(importer);
36.312 + if (!priv->set)
36.313 + {
36.314 + g_object_unref(set);
36.315 + return NULL;
36.316 + }
36.317 + header_version=plover_package_set_get_header_version(unrelocated);
36.318 + if (header_version)
36.319 + plover_package_set_set_header_version(set,header_version);
36.320 + }
36.321 + else
36.322 + {
36.323 + priv->set=plover_package_set_get_razor(unrelocated);
36.324 + razor_set_ref(priv->set);
36.325 + }
36.326 + return set;
36.327 +}
36.328 +
36.329 +PloverPackageSet *plover_package_set_new_from_yum(const char *base,
36.330 + struct razor_relocations *relocations,GError **error)
36.331 +{
36.332 + PloverPackageSet *set;
36.333 + PloverRepository *repository;
36.334 + repository=plover_repository_new_from_yum(base,error);
36.335 + if (!repository)
36.336 + return NULL;
36.337 + set=plover_package_set_new_from_repository(repository,relocations,error);
36.338 + g_object_unref(repository);
36.339 + return set;
36.340 +}
36.341 +
36.342 +PloverPackageSet *plover_package_set_new_from_rpms(const char **filenames,
36.343 + GError **error)
36.344 +{
36.345 + int i;
36.346 + PloverPackageSet *set;
36.347 + PloverPackageSetPrivate *priv;
36.348 + struct razor_importer *importer;
36.349 + struct razor_rpm *rpm;
36.350 + struct razor_error *tmp_error=NULL;
36.351 + importer=razor_importer_create();
36.352 + for(i=0;filenames[i];i++)
36.353 + {
36.354 + rpm=razor_rpm_open(filenames[i],&tmp_error);
36.355 + if (!rpm)
36.356 + {
36.357 + razor_importer_destroy(importer);
36.358 + plover_propagate_razor_error(error,tmp_error);
36.359 + return NULL;
36.360 + }
36.361 + if (razor_importer_add_rpm(importer,rpm))
36.362 + {
36.363 + g_set_error(error,PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED,
36.364 + "%s: failed to import",filenames[i]);
36.365 + razor_importer_destroy(importer);
36.366 + return NULL;
36.367 + }
36.368 + razor_rpm_close(rpm);
36.369 + }
36.370 + set=plover_package_set_new();
36.371 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.372 + priv->set=razor_importer_finish(importer);
36.373 + return set;
36.374 +}
36.375 +
36.376 +uint32_t plover_package_set_get_header_version(PloverPackageSet *set)
36.377 +{
36.378 + PloverPackageSetPrivate *priv;
36.379 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),0);
36.380 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.381 + if (priv->set)
36.382 + return razor_set_get_header_version(priv->set);
36.383 + else
36.384 + return 0;
36.385 +}
36.386 +
36.387 +gboolean plover_package_set_set_header_version(PloverPackageSet *set,
36.388 + uint32_t header_version)
36.389 +{
36.390 + PloverPackageSetPrivate *priv;
36.391 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
36.392 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.393 + if (priv->set)
36.394 + return !razor_set_set_header_version(priv->set,header_version);
36.395 + else
36.396 + return FALSE;
36.397 +}
36.398 +
36.399 +struct razor_set *plover_package_set_get_razor(PloverPackageSet *set)
36.400 +{
36.401 + PloverPackageSetPrivate *priv;
36.402 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.403 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.404 + return priv->set;
36.405 +}
36.406 +
36.407 +GSList *plover_package_set_get_packages(PloverPackageSet *set)
36.408 +{
36.409 + struct razor_package_iterator *iter;
36.410 + struct razor_package *pkg;
36.411 + PloverPackageSetPrivate *priv;
36.412 + PloverPackage *package;
36.413 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.414 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.415 + if (priv->set && !priv->packages)
36.416 + {
36.417 + iter=razor_package_iterator_create(priv->set);
36.418 + while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_LAST))
36.419 + {
36.420 + package=plover_package_new(priv->set,pkg);
36.421 + priv->packages=g_slist_prepend(priv->packages,package);
36.422 + }
36.423 + razor_package_iterator_destroy(iter);
36.424 + priv->packages=g_slist_reverse(priv->packages);
36.425 + }
36.426 + return priv->packages;
36.427 +}
36.428 +
36.429 +PloverPackage *plover_package_set_lookup(PloverPackageSet *set,
36.430 + struct razor_package *razor_package)
36.431 +{
36.432 + GSList *packages,*lnk;
36.433 + PloverPackage *package;
36.434 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.435 + packages=plover_package_set_get_packages(set);
36.436 + for(lnk=packages;lnk;lnk=lnk->next)
36.437 + {
36.438 + package=lnk->data;
36.439 + if (plover_package_get_razor_package(package)==razor_package)
36.440 + return package;
36.441 + }
36.442 + return NULL;
36.443 +}
36.444 +
36.445 +PloverPackage *plover_package_set_find_custom(PloverPackageSet *set,
36.446 + gconstpointer data,GCompareFunc func)
36.447 +{
36.448 + GSList *packages,*lnk;
36.449 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.450 + packages=plover_package_set_get_packages(set);
36.451 + lnk=g_slist_find_custom(packages,data,func);
36.452 + return lnk?lnk->data:NULL;
36.453 +}
36.454 +
36.455 +static gint plover_package_set_compare(gconstpointer a,gconstpointer b)
36.456 +{
36.457 + PloverPackage *pa=(void *)a,*pb=(void *)b;
36.458 + const char *sa,*sb;
36.459 + sa=plover_package_get_name(pa);
36.460 + sb=plover_package_get_name(pb);
36.461 + if (g_strcmp0(sa,sb))
36.462 + return 1;
36.463 + sa=plover_package_get_arch(pa);
36.464 + sb=plover_package_get_arch(pb);
36.465 + if (g_strcmp0(sa,sb))
36.466 + return 1;
36.467 + sa=plover_package_get_version(pa);
36.468 + sb=plover_package_get_version(pb);
36.469 + return !!g_strcmp0(sa,sb);
36.470 +}
36.471 +
36.472 +PloverPackage *plover_package_set_find_matching(PloverPackageSet *set,
36.473 + PloverPackage *template)
36.474 +{
36.475 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.476 + return plover_package_set_find_custom(set,template,
36.477 + plover_package_set_compare);
36.478 +}
36.479 +
36.480 +/*
36.481 + * Some versions of razor have a bug which causes all detail strings
36.482 + * to be discarded. If such a version of razor is used to install or
36.483 + * update a package, then all the detail strings for the installed
36.484 + * set will be lost. This function tests for this condition and can
36.485 + * be used to present something more useful than blank details.
36.486 + */
36.487 +
36.488 +gboolean plover_package_set_get_no_details(PloverPackageSet *set)
36.489 +{
36.490 + PloverPackageSetPrivate *priv;
36.491 + PloverPackage *package;
36.492 + GSList *packages,*link;
36.493 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
36.494 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.495 + if (priv->no_details<0)
36.496 + {
36.497 + packages=plover_package_set_get_packages(set);
36.498 + if (packages)
36.499 + {
36.500 + priv->no_details=0;
36.501 + for(link=packages;link;link=link->next)
36.502 + {
36.503 + package=link->data;
36.504 + priv->no_details+=2;
36.505 + if (*plover_package_get_summary(package))
36.506 + priv->no_details--;
36.507 + if (*plover_package_get_license(package))
36.508 + priv->no_details--;
36.509 + if (*plover_package_get_description(package))
36.510 + priv->no_details--;
36.511 + if (*plover_package_get_URL(package))
36.512 + priv->no_details--;
36.513 + }
36.514 + if (priv->no_details<0) /* More than 50% of strings present */
36.515 + priv->no_details=0;
36.516 + }
36.517 + }
36.518 + return priv->no_details>0;
36.519 +}
36.520 +
36.521 +struct plover_package_set_prefix {
36.522 + gchar *path;
36.523 + guint count;
36.524 +};
36.525 +
36.526 +static GArray *plover_package_set_popchart_new(void)
36.527 +{
36.528 + GArray *prefixes;
36.529 + prefixes=g_array_new(FALSE,FALSE,sizeof(struct plover_package_set_prefix));
36.530 + return prefixes;
36.531 +}
36.532 +
36.533 +static void plover_package_set_popchart_free(GArray *popchart)
36.534 +{
36.535 + int i;
36.536 + struct plover_package_set_prefix *prefix;
36.537 + for(i=0;i<popchart->len;i++)
36.538 + {
36.539 + prefix=&g_array_index(popchart,struct plover_package_set_prefix,i);
36.540 + g_free(prefix->path);
36.541 + }
36.542 + g_array_free(popchart,TRUE);
36.543 +}
36.544 +
36.545 +static void plover_package_set_popchart_add(GArray *popchart,const char *path)
36.546 +{
36.547 + int i;
36.548 + struct plover_package_set_prefix *prefix;
36.549 + for(i=popchart->len-1;i>=0;i--)
36.550 + {
36.551 + prefix=&g_array_index(popchart,struct plover_package_set_prefix,i);
36.552 + if (!strcmp(prefix->path,path))
36.553 + {
36.554 + prefix->count++;
36.555 + return;
36.556 + }
36.557 + }
36.558 + g_array_set_size(popchart,popchart->len+1);
36.559 + prefix=&g_array_index(popchart,struct plover_package_set_prefix,
36.560 + popchart->len-1);
36.561 + prefix->path=g_strdup(path);
36.562 + prefix->count=1;
36.563 +}
36.564 +
36.565 +static const char *plover_package_set_popchart_get_popular(GArray *popchart)
36.566 +{
36.567 + int i;
36.568 + struct plover_package_set_prefix *prefix,*popular;
36.569 + if (!popchart->len)
36.570 + return NULL;
36.571 + popular=&g_array_index(popchart,struct plover_package_set_prefix,0);
36.572 + for(i=1;i<popchart->len;i++)
36.573 + {
36.574 + prefix=&g_array_index(popchart,struct plover_package_set_prefix,i);
36.575 + if (prefix->count>popular->count)
36.576 + popular=prefix;
36.577 + }
36.578 + return popular->path;
36.579 +}
36.580 +
36.581 +static void plover_package_set_popchart_add_prefixes(PloverPackageSet *set,
36.582 + GArray *popchart)
36.583 +{
36.584 + int i;
36.585 + PloverPackage *package;
36.586 + GSList *packages,*lnk;
36.587 + const char *const *prefixes;
36.588 + packages=plover_package_set_get_packages(set);
36.589 + for(lnk=packages;lnk;lnk=lnk->next)
36.590 + {
36.591 + package=lnk->data;
36.592 + prefixes=plover_package_get_prefixes(package);
36.593 + for(i=0;prefixes[i];i++)
36.594 + plover_package_set_popchart_add(popchart,prefixes[i]);
36.595 + }
36.596 +}
36.597 +
36.598 +static void plover_package_set_popchart_add_from_files(PloverPackageSet *set,
36.599 + GArray *popchart)
36.600 +{
36.601 + int len;
36.602 + const char *name,*s;
36.603 + gchar *default_prefix,*path;
36.604 + struct razor_file_iterator *fi;
36.605 + GSList *packages,*lnk;
36.606 + PloverPackage *package;
36.607 + default_prefix=plover_default_prefix_for_vendor("");
36.608 + if (!default_prefix)
36.609 + return;
36.610 + len=strlen(default_prefix);
36.611 + packages=plover_package_set_get_packages(set);
36.612 + for(lnk=packages;lnk;lnk=lnk->next)
36.613 + {
36.614 + package=lnk->data;
36.615 + fi=plover_package_file_iterator_create(package,FALSE);
36.616 + while (razor_file_iterator_next(fi,&name))
36.617 + {
36.618 + if (g_str_has_prefix(name,default_prefix))
36.619 + {
36.620 + for(s=name+len;*s;s++)
36.621 + if (G_IS_DIR_SEPARATOR(*s))
36.622 + break;
36.623 + path=g_strndup(name,s-name);
36.624 + plover_package_set_popchart_add(popchart,path);
36.625 + g_free(path);
36.626 + }
36.627 + }
36.628 + razor_file_iterator_destroy(fi);
36.629 + }
36.630 + g_free(default_prefix);
36.631 +}
36.632 +
36.633 +const char *plover_package_set_guess_prefix(PloverPackageSet *set,
36.634 + GError **error)
36.635 +{
36.636 + GArray *popchart;
36.637 + const char *prefix;
36.638 + PloverPackageSetPrivate *priv;
36.639 + g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
36.640 + priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
36.641 + if (!priv->guessed_prefix)
36.642 + {
36.643 + popchart=plover_package_set_popchart_new();
36.644 + plover_package_set_popchart_add_prefixes(set,popchart);
36.645 + prefix=plover_package_set_popchart_get_popular(popchart);
36.646 + if (prefix)
36.647 + priv->guessed_prefix=g_strdup(prefix);
36.648 + else
36.649 + {
36.650 + plover_package_set_popchart_add_from_files(set,popchart);
36.651 + prefix=plover_package_set_popchart_get_popular(popchart);
36.652 + if (prefix)
36.653 + priv->guessed_prefix=g_strdup(prefix);
36.654 + }
36.655 + plover_package_set_popchart_free(popchart);
36.656 + }
36.657 + if (!priv->guessed_prefix)
36.658 + priv->guessed_prefix=
36.659 + plover_default_prefix_for_vendor("Acme Corporation");
36.660 + return priv->guessed_prefix;
36.661 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/plover/packageset.h Sat Nov 15 19:04:45 2014 +0000
37.3 @@ -0,0 +1,73 @@
37.4 +#ifndef __PLOVER_PACKAGE_SET_H__
37.5 +#define __PLOVER_PACKAGE_SET_H__
37.6 +
37.7 +#include <razor.h>
37.8 +#include <glib-object.h>
37.9 +
37.10 +G_BEGIN_DECLS
37.11 +
37.12 +#define PLOVER_TYPE_PACKAGE_SET plover_package_set_get_type()
37.13 +#define PLOVER_PACKAGE_SET(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
37.14 + PLOVER_TYPE_PACKAGE_SET,PloverPackageSet)
37.15 +#define PLOVER_PACKAGE_SET_CLASS(klass)\
37.16 + G_TYPE_CHECK_CLASS_CAST(klass,\
37.17 + PLOVER_TYPE_PACKAGE_SET,\
37.18 + PloverPackageSetClass)
37.19 +#define PLOVER_IS_PACKAGE_SET(obj)\
37.20 + G_TYPE_CHECK_INSTANCE_TYPE(obj,\
37.21 + PLOVER_TYPE_PACKAGE_SET)
37.22 +#define PLOVER_IS_PACKAGE_SET_CLASS(klass)\
37.23 + G_TYPE_CHECK_CLASS_TYPE(obj,\
37.24 + PLOVER_TYPE_PACKAGE_SET)
37.25 +#define PLOVER_PACKAGE_SET_GET_CLASS(obj)\
37.26 + G_TYPE_INSTANCE_GET_CLASS(obj,\
37.27 + PLOVER_TYPE_PACKAGE_SET,\
37.28 + PloverPackageSetClass)
37.29 +
37.30 +typedef struct _PloverPackageSet {
37.31 + GObject parent_instance;
37.32 +} PloverPackageSet;
37.33 +
37.34 +typedef struct _PloverPackageSetClass {
37.35 + GObjectClass parent_class;
37.36 +} PloverPackageSetClass;
37.37 +
37.38 +#include <plover/repository.h>
37.39 +
37.40 +GType plover_package_set_get_type(void) G_GNUC_CONST;
37.41 +PloverPackageSet *plover_package_set_new(void);
37.42 +void plover_package_set_close(PloverPackageSet *set);
37.43 +gboolean plover_package_set_open(PloverPackageSet *set,const char *install_root,
37.44 + gboolean exclusive,GError **err);
37.45 +gboolean plover_package_set_update(PloverPackageSet *set,struct razor_set *next,
37.46 + struct razor_atomic *atomic);
37.47 +const char *plover_package_set_get_install_root(PloverPackageSet *set);
37.48 +gboolean plover_package_set_get_exclusive(PloverPackageSet *set);
37.49 +PloverPackageSet *plover_package_set_new_from_installed(const char *root,
37.50 + GError **err);
37.51 +PloverPackageSet *plover_package_set_new_from_razor(struct razor_set *razor);
37.52 +PloverPackageSet *
37.53 + plover_package_set_new_from_repository(PloverRepository *repository,
37.54 + struct razor_relocations *relocations,GError **err);
37.55 +PloverPackageSet *plover_package_set_new_from_yum(const char *base,
37.56 + struct razor_relocations *relocations,GError **err);
37.57 +PloverPackageSet *plover_package_set_new_from_rpms(const char **filenames,
37.58 + GError **error);
37.59 +uint32_t plover_package_set_get_header_version(PloverPackageSet *set);
37.60 +gboolean plover_package_set_set_header_version(PloverPackageSet *set,
37.61 + uint32_t header_version);
37.62 +struct razor_set *plover_package_set_get_razor(PloverPackageSet *set);
37.63 +GSList *plover_package_set_get_packages(PloverPackageSet *set);
37.64 +PloverPackage *plover_package_set_lookup(PloverPackageSet *set,
37.65 + struct razor_package *razor_package);
37.66 +PloverPackage *plover_package_set_find_custom(PloverPackageSet *set,
37.67 + gconstpointer data,GCompareFunc func);
37.68 +PloverPackage *plover_package_set_find_matching(PloverPackageSet *set,
37.69 + PloverPackage *template);
37.70 +gboolean plover_package_set_get_no_details(PloverPackageSet *set);
37.71 +const char *plover_package_set_guess_prefix(PloverPackageSet *set,
37.72 + GError **error);
37.73 +
37.74 +G_END_DECLS
37.75 +
37.76 +#endif /* __PLOVER_PACKAGE_SET_H__ */
38.1 --- a/plover/plover.h Fri Mar 23 20:29:50 2012 +0000
38.2 +++ b/plover/plover.h Sat Nov 15 19:04:45 2014 +0000
38.3 @@ -2,6 +2,26 @@
38.4 #define __PLOVER_H__
38.5
38.6 #include <razor.h>
38.7 +#include <glib.h>
38.8 +#include <gio/gio.h>
38.9 +#include <plover/packageset.h>
38.10 +#include <plover/repository.h>
38.11 +
38.12 +#define PLOVER_GENERAL_ERROR RAZOR_ERROR_DOMAIN('P','l','v',0)
38.13 +#define PLOVER_SCRIPTLET_ERROR RAZOR_ERROR_DOMAIN('P','l','v',1)
38.14 +#define PLOVER_RAZOR_ERROR plover_razor_error_quark()
38.15 +#define PLOVER_POSIX_ERROR plover_posix_error_quark()
38.16 +#define PLOVER_MSWIN_ERROR plover_mswin_error_quark()
38.17 +#define PLOVER_ZLIB_ERROR plover_zlib_error_quark()
38.18 +
38.19 +enum plover_general_error
38.20 +{
38.21 + PLOVER_GENERAL_ERROR_FAILED,
38.22 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,
38.23 + PLOVER_GENERAL_ERROR_NO_WORK,
38.24 + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET,
38.25 + PLOVER_GENERAL_ERROR_CANCELLED,
38.26 +};
38.27
38.28 enum comps_requirement_type
38.29 {
38.30 @@ -33,25 +53,36 @@
38.31 struct comps_group *groups;
38.32 };
38.33
38.34 -char *plover_strconcat(const char *string,...);
38.35 -char *plover_default_prefix_for_vendor(const char *vendor);
38.36 +struct plover_vector
38.37 +{
38.38 + int len,alloc;
38.39 + char **strings;
38.40 +};
38.41 +
38.42 +gchar *plover_default_prefix_for_vendor(const char *vendor);
38.43 +gchar *plover_pre_install_prefix(void);
38.44 char *plover_get_program_directory(const char *argv0);
38.45 +GQuark plover_razor_error_quark(void);
38.46 +GQuark plover_posix_error_quark(void);
38.47 +GQuark plover_mswin_error_quark(void);
38.48 +GQuark plover_zlib_error_quark(void);
38.49 +void plover_propagate_razor_error_dup(GError **dest,struct razor_error *src);
38.50 +void plover_propagate_razor_error(GError **dest,struct razor_error *src);
38.51 +void plover_propagate_g_error(struct razor_error **dest,GError *src);
38.52
38.53 -struct razor_set *plover_razor_set_create_from_yum(const char *base);
38.54 +struct razor_set *plover_razor_set_create_from_yum(const char *base,
38.55 + GError **error);
38.56
38.57 -struct razor_set *plover_relocate_packages(struct razor_set *set,
38.58 - const char *base,struct razor_relocations *relocations,
38.59 - struct razor_error **error);
38.60 int plover_run_transaction(struct razor_transaction *trans,
38.61 - struct razor_install_iterator *ii,const char *base,const char *install_root,
38.62 - struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic,
38.63 - struct razor_relocations *relocations,enum razor_stage_type stage);
38.64 -int plover_commit_transaction(struct razor_transaction *trans,const char *base,
38.65 - const char *install_root,struct razor_root *root,
38.66 - struct razor_relocations *relocations);
38.67 -int plover_install(const char *base,const char *prefix,char **pkgs);
38.68 -int plover_update(const char *base,const char *prefix,char **pkgs);
38.69 -int plover_remove(char **pkgs);
38.70 + struct razor_install_iterator *ii,const char *install_root,
38.71 + struct razor_set *system,PloverPackageSet *next,PloverRepository *upstream,
38.72 + struct razor_atomic *atomic,struct razor_relocations *relocations,
38.73 + enum razor_stage_type stage,GCancellable *cancellable);
38.74 +gboolean plover_install(const char *base,const char *prefix,char **pkgs,
38.75 + GError **error);
38.76 +gboolean plover_update(const char *base,const char *prefix,char **pkgs,
38.77 + GError **error);
38.78 +gboolean plover_remove(char **pkgs,GError **error);
38.79 int plover_installed_files_match_prefix(const char *prefix);
38.80
38.81 struct comps *plover_comps_new(void);
38.82 @@ -60,4 +91,15 @@
38.83 struct comps_group *plover_comps_lookup_group(struct comps *comps,
38.84 const char *id);
38.85
38.86 +int plover_log_open(const char *path);
38.87 +
38.88 +struct plover_vector *plover_vector_new(void);
38.89 +struct plover_vector *plover_vector_dup(struct plover_vector *old);
38.90 +void plover_vector_append(struct plover_vector *vector,const char *str);
38.91 +int plover_vector_contains(struct plover_vector *vector,const char *str);
38.92 +int plover_vector_remove(struct plover_vector *vector,const char *str);
38.93 +void plover_vector_sort(struct plover_vector *vector);
38.94 +char *plover_vector_format_for_display(struct plover_vector *vector);
38.95 +void plover_vector_free(struct plover_vector *vector);
38.96 +
38.97 #endif /* __PLOVER_H__ */
39.1 --- a/plover/plover.pc.in Fri Mar 23 20:29:50 2012 +0000
39.2 +++ b/plover/plover.pc.in Sat Nov 15 19:04:45 2014 +0000
39.3 @@ -6,6 +6,6 @@
39.4 Name: plover
39.5 Description: Plover packaging system
39.6 Version: @VERSION@
39.7 -Requires: razor expat zlib
39.8 +Requires: razor expat zlib glib2
39.9 Libs: -L${libdir} -lplover
39.10 Cflags: -I${includedir}
40.1 --- a/plover/razor.c Fri Mar 23 20:29:50 2012 +0000
40.2 +++ b/plover/razor.c Sat Nov 15 19:04:45 2014 +0000
40.3 @@ -1,7 +1,7 @@
40.4 /*
40.5 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
40.6 * Copyright (C) 2008 Red Hat, Inc
40.7 - * Copyright (C) 2009, 2011, 2012 J. Ali Harlow <ali@juiblex.co.uk>
40.8 + * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow <ali@juiblex.co.uk>
40.9 *
40.10 * This program is free software; you can redistribute it and/or modify
40.11 * it under the terms of the GNU General Public License as published by
40.12 @@ -22,10 +22,14 @@
40.13 #include <stdio.h>
40.14 #include <stdarg.h>
40.15 #include <string.h>
40.16 +#include <errno.h>
40.17 #include <unistd.h>
40.18 #include <razor.h>
40.19 +#include <glib.h>
40.20 +#include <gio/gio.h>
40.21 #include "config.h"
40.22 #include "plover/plover.h"
40.23 +#include "plover/transaction.h"
40.24
40.25 static char *rpm_filename(const char *name,const char *version,const char *arch)
40.26 {
40.27 @@ -35,65 +39,7 @@
40.28 v++;
40.29 else
40.30 v=version;
40.31 - return plover_strconcat(name,"-",v,".",arch,".rpm",NULL);
40.32 -}
40.33 -
40.34 -struct razor_set *plover_relocate_packages(struct razor_set *set,
40.35 - const char *base,struct razor_relocations *relocations,
40.36 - struct razor_error **error)
40.37 -{
40.38 - struct razor_importer *importer;
40.39 - struct razor_property_iterator *prop_iter;
40.40 - struct razor_package_iterator *pkg_iter;
40.41 - struct razor_file_iterator *file_iter;
40.42 - struct razor_package *package;
40.43 - struct razor_property *property;
40.44 - struct razor_rpm *rpm;
40.45 - struct razor_set *new;
40.46 - const char *name,*version,*arch,*summary,*desc,*url,*license;
40.47 - char *s,*file;
40.48 - uint32_t flags;
40.49 - importer=razor_importer_create();
40.50 - pkg_iter=razor_package_iterator_create(set);
40.51 - while (razor_package_iterator_next(pkg_iter,&package,RAZOR_DETAIL_NAME,
40.52 - &name,RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
40.53 - RAZOR_DETAIL_SUMMARY,&summary,RAZOR_DETAIL_DESCRIPTION,&desc,
40.54 - RAZOR_DETAIL_URL,&url,RAZOR_DETAIL_LICENSE,&license,RAZOR_DETAIL_LAST))
40.55 - {
40.56 - s=rpm_filename(name,version,arch);
40.57 - file=plover_strconcat(base,"/rpms/",s,NULL);
40.58 - free(s);
40.59 - rpm=razor_rpm_open(file,error);
40.60 - free(file);
40.61 - if (!rpm)
40.62 - {
40.63 - razor_package_iterator_destroy(pkg_iter);
40.64 - razor_importer_destroy(importer);
40.65 - return NULL;
40.66 - }
40.67 - razor_relocations_set_rpm(relocations,rpm);
40.68 - razor_rpm_close(rpm);
40.69 - razor_importer_begin_package(importer,name,version,arch);
40.70 - razor_importer_add_details(importer,summary,desc,url,license);
40.71 - prop_iter=razor_property_iterator_create(set,package);
40.72 - while (razor_property_iterator_next(prop_iter,&property,&name,&flags,
40.73 - &version))
40.74 - razor_importer_add_property(importer,name,flags,version);
40.75 - razor_property_iterator_destroy(prop_iter);
40.76 - file_iter=razor_file_iterator_create(set,package,0);
40.77 - while (razor_file_iterator_next(file_iter,&name))
40.78 - {
40.79 - name=razor_relocations_apply(relocations,name);
40.80 - razor_importer_add_file(importer,name);
40.81 - }
40.82 - razor_file_iterator_destroy(file_iter);
40.83 - razor_importer_finish_package(importer);
40.84 - }
40.85 - razor_package_iterator_destroy(pkg_iter);
40.86 - new=razor_importer_finish(importer);
40.87 - if (new)
40.88 - razor_set_set_header_version(new,razor_set_get_header_version(set));
40.89 - return new;
40.90 + return g_strconcat(name,"-",v,".",arch,".rpm",NULL);
40.91 }
40.92
40.93 /*
40.94 @@ -101,17 +47,20 @@
40.95 * is met (in which case the action is consumed).
40.96 */
40.97 int plover_run_transaction(struct razor_transaction *trans,
40.98 - struct razor_install_iterator *ii,const char *base,const char *install_root,
40.99 - struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic,
40.100 - struct razor_relocations *relocations,enum razor_stage_type stage)
40.101 + struct razor_install_iterator *ii,const char *install_root,
40.102 + struct razor_set *system,PloverPackageSet *next,PloverRepository *upstream,
40.103 + struct razor_atomic *atomic,struct razor_relocations *relocations,
40.104 + enum razor_stage_type stage,GCancellable *cancellable)
40.105 {
40.106 - struct razor_package *package;
40.107 + struct razor_package *pkg;
40.108 enum razor_install_action action;
40.109 struct razor_rpm *rpm;
40.110 struct razor_error *error=NULL;
40.111 const char *name,*version,*arch;
40.112 - char *s,*file;
40.113 + gchar *t;
40.114 int r,count;
40.115 + GError *tmp_error=NULL;
40.116 + PloverPackage *package;
40.117 switch(stage)
40.118 {
40.119 case RAZOR_STAGE_SCRIPTS_PRE:
40.120 @@ -127,40 +76,41 @@
40.121 /* Keep the compiler happy */
40.122 break;
40.123 }
40.124 - while (razor_install_iterator_next(ii,&package,&action,&count))
40.125 + while (razor_install_iterator_next(ii,&pkg,&action,&count))
40.126 {
40.127 + if (g_cancellable_is_cancelled(cancellable))
40.128 + {
40.129 + razor_atomic_abort(atomic,PLOVER_GENERAL_ERROR,
40.130 + PLOVER_GENERAL_ERROR_CANCELLED,"Operation was cancelled");
40.131 + return -1;
40.132 + }
40.133 if (action==RAZOR_INSTALL_ACTION_REMOVE)
40.134 {
40.135 - razor_package_get_details(system,package,RAZOR_DETAIL_NAME,&name,
40.136 + razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
40.137 RAZOR_DETAIL_LAST);
40.138 if (stage==RAZOR_STAGE_FILES)
40.139 printf(" Removing : %s ",name);
40.140 - r=razor_package_remove(system,next,atomic,package,install_root,
40.141 - count,stage);
40.142 + r=razor_package_remove(system,plover_package_set_get_razor(next),
40.143 + atomic,pkg,install_root,count,stage);
40.144 if (stage==RAZOR_STAGE_FILES)
40.145 printf("\n");
40.146 }
40.147 else if (action==RAZOR_INSTALL_ACTION_ADD)
40.148 {
40.149 - razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
40.150 - RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
40.151 - RAZOR_DETAIL_LAST);
40.152 - s=rpm_filename(name,version,arch);
40.153 - file=plover_strconcat(base,"/rpms/",s,NULL);
40.154 - free(s);
40.155 - rpm=razor_rpm_open(file,&error);
40.156 - free(file);
40.157 + package=plover_package_set_lookup(next,pkg);
40.158 + rpm=plover_repository_open_rpm(upstream,package,&tmp_error);
40.159 if (!rpm)
40.160 {
40.161 - razor_atomic_abort(atomic,razor_error_get_msg(error));
40.162 + plover_propagate_g_error(&error,tmp_error);
40.163 + razor_atomic_propagate_error(atomic,error,NULL);
40.164 razor_error_free(error);
40.165 return -1;
40.166 }
40.167 if (stage==RAZOR_STAGE_FILES)
40.168 - printf(" Installing : %s ",name);
40.169 + printf(" Installing : %s ",plover_package_get_name(package));
40.170 if (relocations)
40.171 razor_rpm_set_relocations(rpm,relocations);
40.172 - razor_transaction_fixup_package(trans,package,rpm);
40.173 + razor_transaction_fixup_package(trans,pkg,rpm);
40.174 r=razor_rpm_install(rpm,atomic,install_root,1,stage);
40.175 razor_rpm_close(rpm);
40.176 if (stage==RAZOR_STAGE_FILES)
40.177 @@ -174,9 +124,10 @@
40.178 return -1;
40.179 else if (r)
40.180 {
40.181 - razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
40.182 - RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
40.183 - RAZOR_DETAIL_LAST);
40.184 + package=plover_package_set_lookup(next,pkg);
40.185 + name=plover_package_get_name(package);
40.186 + version=plover_package_get_version(package);
40.187 + arch=plover_package_get_arch(package);
40.188 /*
40.189 * If a pre or preun script fails, then we should
40.190 * treat that as a fatal error. post and postun
40.191 @@ -185,10 +136,12 @@
40.192 */
40.193 if (stage==RAZOR_STAGE_SCRIPTS_PRE)
40.194 {
40.195 - fprintf(stderr,
40.196 - "error: %s(%s-%s.%s) scriptlet failed, exit status %d\n",
40.197 - action==RAZOR_INSTALL_ACTION_ADD?"%pre":"%preun",
40.198 - name,version,arch,r);
40.199 + t=g_strconcat(action==RAZOR_INSTALL_ACTION_ADD?
40.200 + "%pre":"%preun","(",name,"-",version,".",arch,
40.201 + ") scriptlet failed",NULL);
40.202 + fprintf(stderr,"error: %s, exit status %d\n",t,r);
40.203 + razor_atomic_abort(atomic,PLOVER_SCRIPTLET_ERROR,r,t);
40.204 + g_free(t);
40.205 return -1;
40.206 }
40.207 else
40.208 @@ -201,339 +154,70 @@
40.209 return 0;
40.210 }
40.211
40.212 -int plover_commit_transaction(struct razor_transaction *trans,const char *base,
40.213 - const char *install_root,struct razor_root *root,
40.214 - struct razor_relocations *relocations)
40.215 +gboolean plover_install(const char *base,const char *prefix,char **pkgs,
40.216 + GError **error)
40.217 {
40.218 - int r,retval;
40.219 - size_t pos;
40.220 - struct razor_set *system,*next,*set;
40.221 - struct razor_install_iterator *ii;
40.222 - struct razor_atomic *atomic;
40.223 - razor_transaction_resolve(trans);
40.224 - if (razor_transaction_describe(trans)>0)
40.225 - return -1;
40.226 - next=razor_transaction_commit(trans);
40.227 - system=razor_set_ref(razor_root_get_system_set(root));
40.228 - ii=razor_set_create_install_iterator(system,next);
40.229 - do
40.230 - {
40.231 - pos=razor_install_iterator_tell(ii);
40.232 - atomic=razor_atomic_open("package transaction");
40.233 - r=plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
40.234 - relocations,RAZOR_STAGE_SCRIPTS_PRE);
40.235 - if (r<0)
40.236 - fprintf(stderr,"Transaction aborted\n");
40.237 - else
40.238 - {
40.239 - razor_install_iterator_seek(ii,pos);
40.240 - r=plover_run_transaction(trans,ii,base,install_root,system,next,
40.241 - atomic,relocations,RAZOR_STAGE_FILES);
40.242 - if (r==1)
40.243 - {
40.244 - set=razor_install_iterator_commit_set(ii);
40.245 - razor_root_update(root,set,atomic);
40.246 - razor_set_unref(set);
40.247 - }
40.248 - else if (!r)
40.249 - razor_root_update(root,next,atomic);
40.250 - retval=razor_atomic_commit(atomic);
40.251 - if (retval)
40.252 - fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
40.253 - else
40.254 - {
40.255 - razor_install_iterator_seek(ii,pos);
40.256 - plover_run_transaction(trans,ii,base,install_root,system,next,
40.257 - atomic,relocations,RAZOR_STAGE_SCRIPTS_POST);
40.258 - }
40.259 - }
40.260 - razor_atomic_destroy(atomic);
40.261 - } while(!retval && r==1);
40.262 - razor_set_unref(system);
40.263 - razor_set_unref(next);
40.264 - razor_install_iterator_destroy(ii);
40.265 + gboolean retval;
40.266 + PloverTransaction *transaction;
40.267 + transaction=plover_transaction_new_install(base,prefix,pkgs,error);
40.268 + if (!transaction)
40.269 + return FALSE;
40.270 + retval=plover_transaction_commit(transaction,NULL,error);
40.271 + g_object_unref(transaction);
40.272 return retval;
40.273 }
40.274
40.275 -static int plover_mark_package_for_update(struct razor_transaction *trans,
40.276 - struct razor_set *set,const char *pkg)
40.277 +gboolean plover_update(const char *base,const char *prefix,char **pkgs,
40.278 + GError **error)
40.279 {
40.280 - struct razor_package_iterator *pi;
40.281 - struct razor_package *package;
40.282 - const char *name;
40.283 - int retval=-1;
40.284 - pi=razor_package_iterator_create(set);
40.285 - while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
40.286 - RAZOR_DETAIL_LAST))
40.287 + gboolean retval;
40.288 + GError *tmp_error=NULL;
40.289 + PloverTransaction *transaction;
40.290 + transaction=plover_transaction_new_update(base,prefix,pkgs,&tmp_error);
40.291 + if (!transaction)
40.292 {
40.293 - if (!strcmp(name,pkg))
40.294 - {
40.295 - razor_transaction_update_package(trans,package);
40.296 - retval=0;
40.297 - break;
40.298 - }
40.299 + retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT);
40.300 + if (retval)
40.301 + g_error_free(tmp_error);
40.302 + else
40.303 + g_propagate_error(error,tmp_error);
40.304 }
40.305 - razor_package_iterator_destroy(pi);
40.306 + else
40.307 + {
40.308 + retval=plover_transaction_commit(transaction,NULL,error);
40.309 + g_object_unref(transaction);
40.310 + }
40.311 return retval;
40.312 }
40.313
40.314 -int plover_install(const char *base,const char *prefix,char **pkgs)
40.315 +gboolean plover_remove(char **pkgs,GError **error)
40.316 {
40.317 - int i,retval;
40.318 - char *s;
40.319 - char *install_root;
40.320 - struct razor_set *system,*set,*upstream;
40.321 - struct razor_transaction *trans;
40.322 - struct razor_relocations *relocations;
40.323 - struct razor_root *root;
40.324 - struct razor_error *error=NULL;
40.325 - install_root=getenv("RAZOR_ROOT");
40.326 - if (!install_root)
40.327 - install_root="";
40.328 - if (prefix)
40.329 + gboolean retval;
40.330 + GError *tmp_error=NULL;
40.331 + PloverTransaction *transaction;
40.332 + transaction=plover_transaction_new_remove(pkgs,&tmp_error);
40.333 + if (!transaction)
40.334 {
40.335 - relocations=razor_relocations_create();
40.336 - razor_relocations_add(relocations,"/usr",prefix);
40.337 - }
40.338 - else
40.339 - relocations=NULL;
40.340 - root=razor_root_open(install_root,NULL);
40.341 - if (!root)
40.342 - {
40.343 - if (razor_root_create(install_root,&error))
40.344 - root=NULL;
40.345 + retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT);
40.346 + if (retval)
40.347 + {
40.348 + g_error_free(tmp_error);
40.349 + if (pkgs)
40.350 + {
40.351 + g_set_error(error,PLOVER_GENERAL_ERROR,
40.352 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,"%s: %s",pkgs[0],
40.353 + "Package not found");
40.354 + retval=FALSE;
40.355 + }
40.356 + }
40.357 else
40.358 - root=razor_root_open(install_root,&error);
40.359 - if (!root)
40.360 - {
40.361 - fprintf(stderr,"%s\n",razor_error_get_msg(error));
40.362 - razor_error_free(error);
40.363 - if (relocations)
40.364 - razor_relocations_destroy(relocations);
40.365 - return -1;
40.366 - }
40.367 - }
40.368 - system=razor_root_get_system_set(root);
40.369 - if (!system)
40.370 - {
40.371 - fprintf(stderr,"Internal error: No system set\n");
40.372 - razor_root_close(root);
40.373 - if (relocations)
40.374 - razor_relocations_destroy(relocations);
40.375 - return -1;
40.376 - }
40.377 - s=plover_strconcat(base,"/repodata",NULL);
40.378 - if (s)
40.379 - {
40.380 - retval=chdir(s);
40.381 - if (retval<0)
40.382 - perror(s);
40.383 + g_propagate_error(error,tmp_error);
40.384 }
40.385 else
40.386 {
40.387 - fprintf(stderr,"Not enough memory\n");
40.388 - retval=-1;
40.389 + retval=plover_transaction_commit(transaction,NULL,error);
40.390 + g_object_unref(transaction);
40.391 }
40.392 - free(s);
40.393 - if (retval<0)
40.394 - {
40.395 - razor_root_close(root);
40.396 - if (relocations)
40.397 - razor_relocations_destroy(relocations);
40.398 - return -1;
40.399 - }
40.400 - set=plover_razor_set_create_from_yum(base);
40.401 - if (set)
40.402 - {
40.403 - upstream=plover_relocate_packages(set,base,relocations,&error);
40.404 - if (!upstream)
40.405 - {
40.406 - fprintf(stderr,"%s\n",razor_error_get_msg(error));
40.407 - razor_error_free(error);
40.408 - }
40.409 - razor_set_unref(set);
40.410 - }
40.411 - else
40.412 - upstream=NULL;
40.413 - if (!upstream)
40.414 - {
40.415 - razor_root_close(root);
40.416 - if (relocations)
40.417 - razor_relocations_destroy(relocations);
40.418 - return -1;
40.419 - }
40.420 - trans=razor_transaction_create(system,upstream);
40.421 - razor_set_unref(upstream);
40.422 - for(i=0;pkgs[i];i++)
40.423 - if (plover_mark_package_for_update(trans,system,pkgs[i]) &&
40.424 - plover_mark_package_for_update(trans,upstream,pkgs[i]))
40.425 - {
40.426 - fprintf(stderr,"%s: Package not found\n",pkgs[i]);
40.427 - retval=-1;
40.428 - break;
40.429 - }
40.430 - if (!retval)
40.431 - retval=plover_commit_transaction(trans,base,install_root,root,
40.432 - relocations);
40.433 - razor_transaction_destroy(trans);
40.434 - razor_root_close(root);
40.435 - if (relocations)
40.436 - razor_relocations_destroy(relocations);
40.437 - return retval;
40.438 -}
40.439 -
40.440 -int plover_update(const char *base,const char *prefix,char **pkgs)
40.441 -{
40.442 - int i,retval;
40.443 - char *install_root,*s;
40.444 - struct razor_set *system,*set,*upstream;
40.445 - struct razor_transaction *trans;
40.446 - struct razor_relocations *relocations;
40.447 - struct razor_root *root;
40.448 - struct razor_error *error=NULL;
40.449 - install_root=getenv("RAZOR_ROOT");
40.450 - if (!install_root)
40.451 - install_root="";
40.452 - if (prefix)
40.453 - {
40.454 - relocations=razor_relocations_create();
40.455 - razor_relocations_add(relocations,"/usr",prefix);
40.456 - }
40.457 - else
40.458 - relocations=NULL;
40.459 - root=razor_root_open(install_root,&error);
40.460 - if (!root)
40.461 - {
40.462 - fprintf(stderr,"%s\n",razor_error_get_msg(error));
40.463 - razor_error_free(error);
40.464 - if (relocations)
40.465 - razor_relocations_destroy(relocations);
40.466 - return 0;
40.467 - }
40.468 - system=razor_root_get_system_set(root);
40.469 - s=plover_strconcat(base,"/repodata",NULL);
40.470 - if (s)
40.471 - {
40.472 - retval=chdir(s);
40.473 - if (retval)
40.474 - perror(s);
40.475 - }
40.476 - else
40.477 - {
40.478 - fprintf(stderr,"Not enough memory");
40.479 - retval=-1;
40.480 - }
40.481 - free(s);
40.482 - if (retval)
40.483 - {
40.484 - razor_root_close(root);
40.485 - if (relocations)
40.486 - razor_relocations_destroy(relocations);
40.487 - return -1;
40.488 - }
40.489 - set=plover_razor_set_create_from_yum(base);
40.490 - if (set)
40.491 - {
40.492 - upstream=plover_relocate_packages(set,base,relocations,&error);
40.493 - if (!upstream)
40.494 - {
40.495 - fprintf(stderr,"%s\n",razor_error_get_msg(error));
40.496 - razor_error_free(error);
40.497 - }
40.498 - razor_set_unref(set);
40.499 - }
40.500 - else
40.501 - upstream=NULL;
40.502 - if (!upstream)
40.503 - {
40.504 - razor_root_close(root);
40.505 - if (relocations)
40.506 - razor_relocations_destroy(relocations);
40.507 - return -1;
40.508 - }
40.509 - trans=razor_transaction_create(system,upstream);
40.510 - razor_set_unref(upstream);
40.511 - if (pkgs)
40.512 - for(i=0;pkgs[i];i++)
40.513 - {
40.514 - if (plover_mark_package_for_update(trans,system,pkgs[i]))
40.515 - {
40.516 - fprintf(stderr,"%s: Package not found\n",pkgs[i]);
40.517 - retval=-1;
40.518 - break;
40.519 - }
40.520 - }
40.521 - else
40.522 - razor_transaction_update_all(trans);
40.523 - if (!retval)
40.524 - retval=plover_commit_transaction(trans,base,install_root,root,
40.525 - relocations);
40.526 - razor_transaction_destroy(trans);
40.527 - razor_root_close(root);
40.528 - if (relocations)
40.529 - razor_relocations_destroy(relocations);
40.530 - return retval;
40.531 -}
40.532 -
40.533 -static int plover_mark_packages_for_removal(struct razor_transaction *trans,
40.534 - struct razor_set *set,const char *pkg)
40.535 -{
40.536 - struct razor_package_iterator *pi;
40.537 - struct razor_package *package;
40.538 - const char *name;
40.539 - int retval=pkg?-1:0;
40.540 - pi=razor_package_iterator_create(set);
40.541 - while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
40.542 - RAZOR_DETAIL_LAST))
40.543 - {
40.544 - if (!pkg || !strcmp(name,pkg))
40.545 - {
40.546 - razor_transaction_remove_package(trans,package);
40.547 - retval=0;
40.548 - }
40.549 - }
40.550 - razor_package_iterator_destroy(pi);
40.551 - return retval;
40.552 -}
40.553 -
40.554 -int plover_remove(char **pkgs)
40.555 -{
40.556 - int i,retval=0;
40.557 - char *install_root;
40.558 - struct razor_set *system,*upstream;
40.559 - struct razor_transaction *trans;
40.560 - struct razor_root *root;
40.561 - struct razor_error *error=NULL;
40.562 - install_root=getenv("RAZOR_ROOT");
40.563 - if (!install_root)
40.564 - install_root="";
40.565 - root=razor_root_open(install_root,&error);
40.566 - if (!root)
40.567 - {
40.568 - fprintf(stderr,"%s\n",razor_error_get_msg(error));
40.569 - razor_error_free(error);
40.570 - return 0;
40.571 - }
40.572 - system=razor_root_get_system_set(root);
40.573 - upstream=razor_set_create_without_root();
40.574 - trans=razor_transaction_create(system,upstream);
40.575 - razor_set_unref(upstream);
40.576 - if (pkgs)
40.577 - for(i=0;pkgs[i];i++)
40.578 - {
40.579 - if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
40.580 - {
40.581 - fprintf(stderr,"%s: Package not found\n",pkgs[i]);
40.582 - retval=-1;
40.583 - break;
40.584 - }
40.585 - }
40.586 - else
40.587 - plover_mark_packages_for_removal(trans,system,NULL);
40.588 - if (!retval)
40.589 - retval=plover_commit_transaction(trans,NULL,install_root,root,NULL);
40.590 - razor_transaction_destroy(trans);
40.591 - razor_root_close(root);
40.592 return retval;
40.593 }
40.594
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/plover/repository.c Sat Nov 15 19:04:45 2014 +0000
41.3 @@ -0,0 +1,168 @@
41.4 +/*
41.5 + * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
41.6 + *
41.7 + * This program is free software; you can redistribute it and/or modify
41.8 + * it under the terms of the GNU General Public License as published by
41.9 + * the Free Software Foundation; either version 2 of the License, or
41.10 + * (at your option) any later version.
41.11 + *
41.12 + * This program is distributed in the hope that it will be useful,
41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41.15 + * GNU General Public License for more details.
41.16 + *
41.17 + * You should have received a copy of the GNU General Public License along
41.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
41.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
41.20 + */
41.21 +
41.22 +#include "config.h"
41.23 +#include <stdlib.h>
41.24 +#include <string.h>
41.25 +#include <glib-object.h>
41.26 +#include <razor.h>
41.27 +#include <plover/plover.h>
41.28 +#include <plover/repository.h>
41.29 +
41.30 +G_DEFINE_TYPE(PloverRepository,plover_repository,G_TYPE_OBJECT);
41.31 +
41.32 +typedef struct _PloverRepositoryPrivate {
41.33 + PloverPackageSet *set;
41.34 + gchar **filenames;
41.35 +} PloverRepositoryPrivate;
41.36 +
41.37 +#define PLOVER_REPOSITORY_GET_PRIVATE(obj)\
41.38 + G_TYPE_INSTANCE_GET_PRIVATE(obj,\
41.39 + PLOVER_TYPE_REPOSITORY,\
41.40 + PloverRepositoryPrivate)
41.41 +
41.42 +static void plover_repository_finalize(GObject *obj)
41.43 +{
41.44 + PloverRepositoryPrivate *priv=PLOVER_REPOSITORY_GET_PRIVATE(obj);
41.45 + g_strfreev(priv->filenames);
41.46 + if (G_OBJECT_CLASS(plover_repository_parent_class)->finalize)
41.47 + G_OBJECT_CLASS(plover_repository_parent_class)->finalize(obj);
41.48 +}
41.49 +
41.50 +static void plover_repository_dispose(GObject *obj)
41.51 +{
41.52 + PloverRepositoryPrivate *priv=PLOVER_REPOSITORY_GET_PRIVATE(obj);
41.53 + g_clear_object(&priv->set);
41.54 + if (G_OBJECT_CLASS(plover_repository_parent_class)->dispose)
41.55 + G_OBJECT_CLASS(plover_repository_parent_class)->dispose(obj);
41.56 +}
41.57 +
41.58 +static void plover_repository_class_init(PloverRepositoryClass *klass)
41.59 +{
41.60 + GObjectClass *oclass=G_OBJECT_CLASS(klass);
41.61 + oclass->finalize=plover_repository_finalize;
41.62 + oclass->dispose=plover_repository_dispose;
41.63 + g_type_class_add_private(klass,sizeof(PloverRepositoryPrivate));
41.64 +}
41.65 +
41.66 +static void plover_repository_init(PloverRepository *repository)
41.67 +{
41.68 +}
41.69 +
41.70 +PloverRepository *plover_repository_new_from_files(const char **filenames,
41.71 + GError **error)
41.72 +{
41.73 + PloverPackageSet *set;
41.74 + PloverRepository *repository;
41.75 + PloverRepositoryPrivate *priv;
41.76 + set=plover_package_set_new_from_rpms(filenames,error);
41.77 + if (!set)
41.78 + return NULL;
41.79 + repository=g_object_new(PLOVER_TYPE_REPOSITORY,NULL);
41.80 + priv=PLOVER_REPOSITORY_GET_PRIVATE(repository);
41.81 + priv->filenames=g_strdupv((gchar **)filenames);
41.82 + priv->set=set;
41.83 + return repository;
41.84 +}
41.85 +
41.86 +static char *rpm_filename(const char *name,const char *version,const char *arch)
41.87 +{
41.88 + const char *v;
41.89 + v=strchr(version,':'); /* Skip epoch */
41.90 + if (v)
41.91 + v++;
41.92 + else
41.93 + v=version;
41.94 + return g_strconcat(name,"-",v,".",arch,".rpm",NULL);
41.95 +}
41.96 +
41.97 +PloverRepository *plover_repository_new_from_yum(const char *base,
41.98 + GError **error)
41.99 +{
41.100 + char *s;
41.101 + const char *name,*version,*arch;
41.102 + GPtrArray *filenames;
41.103 + struct razor_set *imported;
41.104 + struct razor_package *package;
41.105 + struct razor_package_iterator *pi;
41.106 + PloverPackageSet *set;
41.107 + PloverRepository *repository;
41.108 + PloverRepositoryPrivate *priv;
41.109 + imported=plover_razor_set_create_from_yum(base,error);
41.110 + if (!imported)
41.111 + return NULL;
41.112 + set=plover_package_set_new_from_razor(imported);
41.113 + razor_set_unref(imported);
41.114 + repository=g_object_new(PLOVER_TYPE_REPOSITORY,NULL);
41.115 + priv=PLOVER_REPOSITORY_GET_PRIVATE(repository);
41.116 + filenames=g_ptr_array_new();
41.117 + pi=razor_package_iterator_create(plover_package_set_get_razor(set));
41.118 + while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
41.119 + RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,RAZOR_DETAIL_LAST))
41.120 + {
41.121 + s=rpm_filename(name,version,arch);
41.122 + g_ptr_array_add(filenames,g_build_filename(base,"rpms",s,NULL));
41.123 + free(s);
41.124 + }
41.125 + razor_package_iterator_destroy(pi);
41.126 + g_ptr_array_add(filenames,NULL);
41.127 + priv->filenames=(gchar **)g_ptr_array_free(filenames,FALSE);
41.128 + priv->set=set;
41.129 + return repository;
41.130 +}
41.131 +
41.132 +PloverPackageSet *
41.133 + plover_repository_get_package_set(PloverRepository *repository)
41.134 +{
41.135 + PloverRepositoryPrivate *priv;
41.136 + g_return_val_if_fail(PLOVER_IS_REPOSITORY(repository),NULL);
41.137 + priv=PLOVER_REPOSITORY_GET_PRIVATE(repository);
41.138 + return priv->set;
41.139 +}
41.140 +
41.141 +struct razor_rpm *plover_repository_open_rpm(PloverRepository *repository,
41.142 + PloverPackage *package,GError **error)
41.143 +{
41.144 + int nth;
41.145 + struct razor_rpm *rpm;
41.146 + struct razor_error *tmp_error=NULL;
41.147 + PloverRepositoryPrivate *priv;
41.148 + PloverPackage *internal;
41.149 + g_return_val_if_fail(PLOVER_IS_REPOSITORY(repository),NULL);
41.150 + g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
41.151 + priv=PLOVER_REPOSITORY_GET_PRIVATE(repository);
41.152 + nth=g_slist_index(plover_package_set_get_packages(priv->set),package);
41.153 + if (nth<0)
41.154 + {
41.155 + internal=plover_package_set_find_matching(priv->set,package);
41.156 + nth=g_slist_index(plover_package_set_get_packages(priv->set),internal);
41.157 + }
41.158 + if (nth<0)
41.159 + {
41.160 + g_set_error(error,PLOVER_GENERAL_ERROR,
41.161 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,
41.162 + "%s-%s.%s: Package not in repository",
41.163 + plover_package_get_name(package),plover_package_get_version(package),
41.164 + plover_package_get_arch(package));
41.165 + return NULL;
41.166 + }
41.167 + rpm=razor_rpm_open(priv->filenames[nth],&tmp_error);
41.168 + if (!rpm)
41.169 + plover_propagate_razor_error(error,tmp_error);
41.170 + return rpm;
41.171 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/plover/repository.h Sat Nov 15 19:04:45 2014 +0000
42.3 @@ -0,0 +1,49 @@
42.4 +#ifndef __PLOVER_REPOSITORY_H__
42.5 +#define __PLOVER_REPOSITORY_H__
42.6 +
42.7 +#include <razor.h>
42.8 +#include <glib-object.h>
42.9 +#include <gio/gio.h>
42.10 +
42.11 +G_BEGIN_DECLS
42.12 +
42.13 +#define PLOVER_TYPE_REPOSITORY plover_repository_get_type()
42.14 +#define PLOVER_REPOSITORY(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
42.15 + PLOVER_TYPE_REPOSITORY,PloverRepository)
42.16 +#define PLOVER_REPOSITORY_CLASS(klass)\
42.17 + G_TYPE_CHECK_CLASS_CAST(klass,\
42.18 + PLOVER_TYPE_REPOSITORY,PloverRepositoryClass)
42.19 +#define PLOVER_IS_REPOSITORY(obj)\
42.20 + G_TYPE_CHECK_INSTANCE_TYPE(obj,\
42.21 + PLOVER_TYPE_REPOSITORY)
42.22 +#define PLOVER_IS_REPOSITORY_CLASS(klass)\
42.23 + G_TYPE_CHECK_CLASS_TYPE(obj,\
42.24 + PLOVER_TYPE_REPOSITORY)
42.25 +#define PLOVER_REPOSITORY_GET_CLASS(obj)\
42.26 + G_TYPE_INSTANCE_GET_CLASS(obj,\
42.27 + PLOVER_TYPE_REPOSITORY,PloverRepositoryClass)
42.28 +
42.29 +typedef struct _PloverRepository {
42.30 + GObject parent_instance;
42.31 +} PloverRepository;
42.32 +
42.33 +typedef struct _PloverRepositoryClass {
42.34 + GObjectClass parent_class;
42.35 +} PloverRepositoryClass;
42.36 +
42.37 +#include <plover/package.h>
42.38 +#include <plover/packageset.h>
42.39 +
42.40 +GType plover_repository_get_type(void) G_GNUC_CONST;
42.41 +PloverRepository *plover_repository_new_from_files(const char **filenames,
42.42 + GError **error);
42.43 +PloverRepository *plover_repository_new_from_yum(const char *base,
42.44 + GError **error);
42.45 +PloverPackageSet *
42.46 + plover_repository_get_package_set(PloverRepository *repository);
42.47 +struct razor_rpm *plover_repository_open_rpm(PloverRepository *repository,
42.48 + PloverPackage *package,GError **error);
42.49 +
42.50 +G_END_DECLS
42.51 +
42.52 +#endif /* __PLOVER_REPOSITORY_H__ */
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/plover/transaction.c Sat Nov 15 19:04:45 2014 +0000
43.3 @@ -0,0 +1,722 @@
43.4 +/*
43.5 + * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow <ali@juiblex.co.uk>
43.6 + *
43.7 + * This program is free software; you can redistribute it and/or modify
43.8 + * it under the terms of the GNU General Public License as published by
43.9 + * the Free Software Foundation; either version 2 of the License, or
43.10 + * (at your option) any later version.
43.11 + *
43.12 + * This program is distributed in the hope that it will be useful,
43.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
43.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43.15 + * GNU General Public License for more details.
43.16 + *
43.17 + * You should have received a copy of the GNU General Public License along
43.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
43.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43.20 + */
43.21 +
43.22 +#include "config.h"
43.23 +#include <stdlib.h>
43.24 +#include <string.h>
43.25 +#include <errno.h>
43.26 +#include <unistd.h>
43.27 +#include <glib-object.h>
43.28 +#include "plover/transaction.h"
43.29 +#include "plover/plover.h"
43.30 +
43.31 +G_DEFINE_TYPE(PloverTransaction,plover_transaction,G_TYPE_OBJECT);
43.32 +
43.33 +enum {
43.34 + STATUS_CHANGED=0,
43.35 + N_SIGNALS
43.36 +};
43.37 +
43.38 +static guint signals[N_SIGNALS];
43.39 +
43.40 +static void plover_transaction_finalize(PloverTransaction *transaction)
43.41 +{
43.42 + g_free(transaction->base);
43.43 + g_free(transaction->prefix);
43.44 + g_free(transaction->unsatisfied);
43.45 + if (transaction->trans)
43.46 + razor_transaction_destroy(transaction->trans);
43.47 + if (transaction->relocations)
43.48 + razor_relocations_destroy(transaction->relocations);
43.49 + if (transaction->install_iterator)
43.50 + razor_install_iterator_destroy(transaction->install_iterator);
43.51 + if (transaction->next)
43.52 + razor_set_unref(transaction->next);
43.53 + if (transaction->system)
43.54 + razor_set_unref(transaction->system);
43.55 +}
43.56 +
43.57 +static void plover_transaction_dispose(PloverTransaction *transaction)
43.58 +{
43.59 + g_clear_object(&transaction->installed);
43.60 + g_clear_object(&transaction->relocated);
43.61 + g_clear_object(&transaction->upstream);
43.62 +}
43.63 +
43.64 +static void plover_transaction_class_init(PloverTransactionClass *klass)
43.65 +{
43.66 + GObjectClass *gobject_class=G_OBJECT_CLASS(klass);
43.67 + gobject_class->finalize=(void (*)(GObject *))plover_transaction_finalize;
43.68 + gobject_class->dispose=(void (*)(GObject *))plover_transaction_dispose;
43.69 + signals[STATUS_CHANGED]=g_signal_new("status-changed",
43.70 + G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,0,NULL,NULL,
43.71 + g_cclosure_marshal_VOID__STRING,G_TYPE_NONE,1,G_TYPE_STRING);
43.72 +}
43.73 +
43.74 +static void plover_transaction_init(PloverTransaction *transaction)
43.75 +{
43.76 +}
43.77 +
43.78 +gboolean plover_transaction_resolve(PloverTransaction *transaction,
43.79 + GError **error)
43.80 +{
43.81 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.82 + if (!(transaction->flags&PLOVER_TRANSACTION_RESOLVED))
43.83 + {
43.84 + razor_transaction_resolve(transaction->trans);
43.85 + transaction->flags|=PLOVER_TRANSACTION_RESOLVED;
43.86 + g_free(transaction->unsatisfied);
43.87 + transaction->unsatisfied=NULL;
43.88 + if (razor_transaction_describe(transaction->trans)>0)
43.89 + transaction->flags|=PLOVER_TRANSACTION_UNSATISFIED;
43.90 + }
43.91 + if (transaction->flags&PLOVER_TRANSACTION_UNSATISFIED)
43.92 + {
43.93 + g_set_error(error,PLOVER_GENERAL_ERROR,
43.94 + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET,
43.95 + "Package requirements not met");
43.96 + return FALSE;
43.97 + }
43.98 + return TRUE;
43.99 +}
43.100 +
43.101 +static void plover_transaction_unsatisfied_callback(const char *requirement,
43.102 + struct razor_package *package,const char *name,const char *version,
43.103 + const char *arch,void *data)
43.104 +{
43.105 + GString *string=data;
43.106 + g_string_append_printf(string,"%s is needed by %s-%s.%s\n",requirement,name,
43.107 + version,arch);
43.108 +}
43.109 +
43.110 +const char *plover_transaction_get_unsatisfied(PloverTransaction *transaction)
43.111 +{
43.112 + GString *unsatisfied;
43.113 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),NULL);
43.114 + if (plover_transaction_resolve(transaction,NULL))
43.115 + return NULL;
43.116 + else if (!transaction->unsatisfied)
43.117 + {
43.118 + unsatisfied=g_string_new(NULL);
43.119 + if (!razor_transaction_unsatisfied(transaction->trans,
43.120 + plover_transaction_unsatisfied_callback,unsatisfied))
43.121 + /* Impossible */
43.122 + g_string_assign(unsatisfied,
43.123 + "Unknown package requirements unsatisfied");
43.124 + transaction->unsatisfied=g_string_free(unsatisfied,FALSE);
43.125 + }
43.126 + return transaction->unsatisfied;
43.127 +}
43.128 +
43.129 +struct razor_set *plover_transaction_get_system_set(
43.130 + PloverTransaction *transaction)
43.131 +{
43.132 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),NULL);
43.133 + if (!transaction->system && transaction->installed)
43.134 + {
43.135 + transaction->system=
43.136 + plover_package_set_get_razor(transaction->installed);
43.137 + if (transaction->system)
43.138 + razor_set_ref(transaction->system);
43.139 + }
43.140 + return transaction->system;
43.141 +}
43.142 +
43.143 +struct razor_set *plover_transaction_get_next_set(
43.144 + PloverTransaction *transaction,GError **error)
43.145 +{
43.146 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),NULL);
43.147 + if (!transaction->next)
43.148 + {
43.149 + if (!plover_transaction_resolve(transaction,error))
43.150 + return NULL;
43.151 + transaction->next=razor_transaction_commit(transaction->trans);
43.152 + }
43.153 + return transaction->next;
43.154 +}
43.155 +
43.156 +struct razor_install_iterator *plover_transaction_get_install_iterator(
43.157 + PloverTransaction *transaction,GError **error)
43.158 +{
43.159 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),NULL);
43.160 + if (!transaction->install_iterator)
43.161 + {
43.162 + if (!plover_transaction_get_next_set(transaction,error))
43.163 + return NULL;
43.164 + (void)plover_transaction_get_system_set(transaction);
43.165 + transaction->install_iterator=
43.166 + razor_set_create_install_iterator(transaction->system,
43.167 + transaction->next);
43.168 + }
43.169 + razor_install_iterator_rewind(transaction->install_iterator);
43.170 + return transaction->install_iterator;
43.171 +}
43.172 +
43.173 +gboolean plover_transaction_commit(PloverTransaction *transaction,
43.174 + GCancellable *cancellable,GError **error)
43.175 +{
43.176 + int r;
43.177 + gboolean retval;
43.178 + size_t pos;
43.179 + struct razor_set *set;
43.180 + struct razor_install_iterator *ii;
43.181 + struct razor_atomic *atomic;
43.182 + PloverPackageSet *next;
43.183 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.184 + if (g_cancellable_set_error_if_cancelled(cancellable,error))
43.185 + return FALSE;
43.186 + ii=plover_transaction_get_install_iterator(transaction,error);
43.187 + if (!ii)
43.188 + return FALSE;
43.189 + do
43.190 + {
43.191 + if (g_cancellable_set_error_if_cancelled(cancellable,error))
43.192 + return FALSE;
43.193 + pos=razor_install_iterator_tell(ii);
43.194 + g_signal_emit(transaction,signals[STATUS_CHANGED],0,
43.195 + "Running pre-transaction scripts");
43.196 + atomic=razor_atomic_open("package transaction");
43.197 + next=plover_package_set_new_from_razor(transaction->next);
43.198 + r=plover_run_transaction(transaction->trans,ii,
43.199 + plover_package_set_get_install_root(transaction->installed),
43.200 + transaction->system,next,transaction->upstream,atomic,
43.201 + transaction->relocations,RAZOR_STAGE_SCRIPTS_PRE,cancellable);
43.202 + if (r<0)
43.203 + {
43.204 + g_signal_emit(transaction,signals[STATUS_CHANGED],0,
43.205 + "Failed in pre-transaction scripts");
43.206 + plover_propagate_razor_error_dup(error,
43.207 + razor_atomic_get_error(atomic));
43.208 + razor_atomic_destroy(atomic);
43.209 + g_object_unref(next);
43.210 + return FALSE;
43.211 + }
43.212 + else
43.213 + {
43.214 + g_signal_emit(transaction,signals[STATUS_CHANGED],0,
43.215 + "Unpacking files");
43.216 + razor_install_iterator_seek(ii,pos);
43.217 + r=plover_run_transaction(transaction->trans,ii,
43.218 + plover_package_set_get_install_root(transaction->installed),
43.219 + transaction->system,next,transaction->upstream,
43.220 + atomic,transaction->relocations,RAZOR_STAGE_FILES,
43.221 +#if RAZOR_HAVE_ATOMIC_ROLLBACK
43.222 + cancellable);
43.223 +#else
43.224 + NULL);
43.225 +#endif
43.226 + if (r==1)
43.227 + {
43.228 + set=razor_install_iterator_commit_set(ii);
43.229 + plover_package_set_update(transaction->installed,set,atomic);
43.230 + razor_set_unref(set);
43.231 + }
43.232 + else if (!r)
43.233 + plover_package_set_update(transaction->installed,
43.234 + transaction->next,atomic);
43.235 + retval=!razor_atomic_commit(atomic);
43.236 + if (!retval)
43.237 + {
43.238 + g_signal_emit(transaction,signals[STATUS_CHANGED],0,
43.239 + "Failed to unpack all files correctly");
43.240 + plover_propagate_razor_error_dup(error,
43.241 + razor_atomic_get_error(atomic));
43.242 + }
43.243 + else
43.244 + {
43.245 + g_signal_emit(transaction,signals[STATUS_CHANGED],0,
43.246 + "Running post-transaction scripts");
43.247 + razor_install_iterator_seek(ii,pos);
43.248 + plover_run_transaction(transaction->trans,ii,
43.249 + plover_package_set_get_install_root(transaction->installed),
43.250 + transaction->system,next,transaction->upstream,
43.251 + atomic,transaction->relocations,RAZOR_STAGE_SCRIPTS_POST,
43.252 + NULL);
43.253 + }
43.254 + }
43.255 + razor_atomic_destroy(atomic);
43.256 + g_object_unref(next);
43.257 + } while(retval && r==1);
43.258 + g_signal_emit(transaction,signals[STATUS_CHANGED],0,"Completed");
43.259 + return retval;
43.260 +}
43.261 +
43.262 +static void plover_transaction_commit_async_thread(GTask *task,
43.263 + gpointer source_object,gpointer task_data,GCancellable *cancellable)
43.264 +{
43.265 + PloverTransaction *transaction=source_object;
43.266 + GError *error=NULL;
43.267 + if (!plover_transaction_commit(transaction,cancellable,&error))
43.268 + g_task_return_error(task,error);
43.269 + else
43.270 + g_task_return_boolean(task,TRUE);
43.271 + g_object_unref(task);
43.272 +}
43.273 +
43.274 +void plover_transaction_commit_async(PloverTransaction *transaction,
43.275 + GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data)
43.276 +{
43.277 + GTask *task;
43.278 + g_return_if_fail(PLOVER_IS_TRANSACTION(transaction));
43.279 + task=g_task_new(transaction,cancellable,callback,user_data);
43.280 + g_task_run_in_thread(task,plover_transaction_commit_async_thread);
43.281 +}
43.282 +
43.283 +gboolean plover_transaction_commit_finish(PloverTransaction *transaction,
43.284 + GAsyncResult *result,GError **error)
43.285 +{
43.286 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.287 + g_return_val_if_fail(g_task_is_valid(result,transaction),FALSE);
43.288 + return g_task_propagate_boolean(G_TASK(result),error);
43.289 +}
43.290 +
43.291 +static int plover_mark_package_for_update(struct razor_transaction *trans,
43.292 + struct razor_set *set,const char *pkg)
43.293 +{
43.294 + struct razor_package_iterator *pi;
43.295 + struct razor_package *package;
43.296 + const char *name;
43.297 + int retval=-1;
43.298 + pi=razor_package_iterator_create(set);
43.299 + while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
43.300 + RAZOR_DETAIL_LAST))
43.301 + {
43.302 + if (!strcmp(name,pkg))
43.303 + {
43.304 + razor_transaction_update_package(trans,package);
43.305 + retval=0;
43.306 + break;
43.307 + }
43.308 + }
43.309 + razor_package_iterator_destroy(pi);
43.310 + return retval;
43.311 +}
43.312 +
43.313 +PloverTransaction *plover_transaction_new(void)
43.314 +{
43.315 + return PLOVER_TRANSACTION(g_object_new(PLOVER_TYPE_TRANSACTION,NULL));
43.316 +}
43.317 +
43.318 +void plover_transaction_set_prefix(PloverTransaction *transaction,
43.319 + const char *prefix)
43.320 +{
43.321 + g_return_if_fail(PLOVER_IS_TRANSACTION(transaction));
43.322 + g_return_if_fail(transaction->upstream == NULL);
43.323 + if (!g_strcmp0(prefix,transaction->prefix))
43.324 + return;
43.325 + if (transaction->relocations)
43.326 + razor_relocations_destroy(transaction->relocations);
43.327 + g_free(transaction->prefix);
43.328 + if (prefix)
43.329 + {
43.330 + transaction->relocations=razor_relocations_create();
43.331 + razor_relocations_add(transaction->relocations,"/usr",prefix);
43.332 + }
43.333 + else
43.334 + transaction->relocations=NULL;
43.335 + transaction->prefix=g_strdup(prefix);
43.336 +}
43.337 +
43.338 +void plover_transaction_set_installed(PloverTransaction *transaction,
43.339 + PloverPackageSet *installed)
43.340 +{
43.341 + g_return_if_fail(PLOVER_IS_TRANSACTION(transaction));
43.342 + g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed));
43.343 + if (transaction->installed)
43.344 + g_object_unref(transaction->installed);
43.345 + transaction->installed=g_object_ref(installed);
43.346 +}
43.347 +
43.348 +gboolean plover_transaction_root_open(PloverTransaction *transaction,
43.349 + const char *install_root,GError **error)
43.350 +{
43.351 + PloverPackageSet *installed;
43.352 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.353 + if (!install_root)
43.354 + install_root=g_getenv("RAZOR_ROOT");
43.355 + if (!install_root)
43.356 + install_root="";
43.357 + if (transaction->installed && !g_strcmp0(install_root,
43.358 + plover_package_set_get_install_root(transaction->installed)))
43.359 + return TRUE;
43.360 + installed=plover_package_set_new();
43.361 + if (!plover_package_set_open(installed,install_root,TRUE,error))
43.362 + {
43.363 + g_object_unref(installed);
43.364 + return FALSE;
43.365 + }
43.366 + if (transaction->installed)
43.367 + g_object_unref(transaction->installed);
43.368 + transaction->installed=installed;
43.369 + return TRUE;
43.370 +}
43.371 +
43.372 +struct razor_set *plover_transaction_import_yum(PloverTransaction *transaction,
43.373 + const char *base,GError **error)
43.374 +{
43.375 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),NULL);
43.376 + g_return_val_if_fail(transaction->base == NULL,NULL);
43.377 + transaction->base=g_strdup(base);
43.378 + return plover_razor_set_create_from_yum(base,error);
43.379 +}
43.380 +
43.381 +gboolean plover_transaction_set_upstream(PloverTransaction *transaction,
43.382 + PloverRepository *upstream,GError **error)
43.383 +{
43.384 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.385 + g_return_val_if_fail(PLOVER_IS_REPOSITORY(upstream),FALSE);
43.386 + g_return_val_if_fail(transaction->upstream == NULL,FALSE);
43.387 + transaction->relocated=plover_package_set_new_from_repository(upstream,
43.388 + transaction->relocations,error);
43.389 + if (transaction->relocated)
43.390 + transaction->upstream=g_object_ref(upstream);
43.391 + return !!transaction->relocated;
43.392 +}
43.393 +
43.394 +gboolean
43.395 + plover_transaction_set_upstream_from_yum(PloverTransaction *transaction,
43.396 + const char *base,GError **error)
43.397 +{
43.398 + gboolean retval;
43.399 + PloverRepository *upstream;
43.400 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.401 + g_return_val_if_fail(transaction->upstream == NULL,FALSE);
43.402 + upstream=plover_repository_new_from_yum(base,error);
43.403 + if (!upstream)
43.404 + return FALSE;
43.405 + retval=plover_transaction_set_upstream(transaction,upstream,error);
43.406 + g_object_unref(upstream);
43.407 + return retval;
43.408 +}
43.409 +
43.410 +gboolean plover_transaction_install(PloverTransaction *transaction,
43.411 + char **pkgs,GError **error)
43.412 +{
43.413 + int i;
43.414 + struct razor_set *system,*upstream;
43.415 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.416 + g_return_val_if_fail(transaction->upstream != NULL,FALSE);
43.417 + g_return_val_if_fail(transaction->trans == NULL,FALSE);
43.418 + if (!plover_transaction_root_open(transaction,NULL,error))
43.419 + return FALSE;
43.420 + system=plover_transaction_get_system_set(transaction);
43.421 + if (!system)
43.422 + {
43.423 + g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
43.424 + "Internal error: No system set");
43.425 + return FALSE;
43.426 + }
43.427 + upstream=plover_package_set_get_razor(transaction->relocated);
43.428 + transaction->trans=razor_transaction_create(system,upstream);
43.429 + for(i=0;pkgs[i];i++)
43.430 + if (plover_mark_package_for_update(transaction->trans,system,pkgs[i]) &&
43.431 + plover_mark_package_for_update(transaction->trans,upstream,pkgs[i]))
43.432 + {
43.433 + g_set_error(error,PLOVER_GENERAL_ERROR,
43.434 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,"%s: %s",pkgs[i],
43.435 + "Package not found");
43.436 + razor_transaction_destroy(transaction->trans);
43.437 + transaction->trans=NULL;
43.438 + return FALSE;
43.439 + break;
43.440 + }
43.441 + return TRUE;
43.442 +}
43.443 +
43.444 +gboolean plover_transaction_update(PloverTransaction *transaction,
43.445 + char **pkgs,GError **error)
43.446 +{
43.447 + int i;
43.448 + struct razor_set *system,*upstream;
43.449 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.450 + g_return_val_if_fail(transaction->upstream != NULL,FALSE);
43.451 + g_return_val_if_fail(transaction->trans == NULL,FALSE);
43.452 + if (!plover_transaction_root_open(transaction,NULL,error))
43.453 + return FALSE;
43.454 + system=plover_transaction_get_system_set(transaction);
43.455 + if (!system)
43.456 + {
43.457 + g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
43.458 + "Internal error: No system set");
43.459 + return FALSE;
43.460 + }
43.461 + upstream=plover_package_set_get_razor(transaction->relocated);
43.462 + transaction->trans=razor_transaction_create(system,upstream);
43.463 + if (!pkgs)
43.464 + razor_transaction_update_all(transaction->trans);
43.465 + else
43.466 + for(i=0;pkgs[i];i++)
43.467 + if (plover_mark_package_for_update(transaction->trans,system,
43.468 + pkgs[i]))
43.469 + {
43.470 + g_set_error(error,PLOVER_GENERAL_ERROR,
43.471 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,"%s: %s",pkgs[i],
43.472 + "Package not found");
43.473 + razor_transaction_destroy(transaction->trans);
43.474 + transaction->trans=NULL;
43.475 + return FALSE;
43.476 + break;
43.477 + }
43.478 + return TRUE;
43.479 +}
43.480 +
43.481 +PloverTransaction *plover_transaction_new_install(const char *base,
43.482 + const char *prefix,char **pkgs,GError **error)
43.483 +{
43.484 + PloverTransaction *transaction;
43.485 + transaction=plover_transaction_new();
43.486 + plover_transaction_set_prefix(transaction,prefix);
43.487 + if (!plover_transaction_set_upstream_from_yum(transaction,base,error))
43.488 + {
43.489 + g_object_unref(transaction);
43.490 + return NULL;
43.491 + }
43.492 + if (!plover_transaction_install(transaction,pkgs,error))
43.493 + {
43.494 + g_object_unref(transaction);
43.495 + return NULL;
43.496 + }
43.497 + return transaction;
43.498 +}
43.499 +
43.500 +PloverTransaction *plover_transaction_new_update(const char *base,
43.501 + const char *prefix,char **pkgs,GError **error)
43.502 +{
43.503 + PloverTransaction *transaction;
43.504 + transaction=plover_transaction_new();
43.505 + plover_transaction_set_prefix(transaction,prefix);
43.506 + if (!plover_transaction_set_upstream_from_yum(transaction,base,error))
43.507 + {
43.508 + g_object_unref(transaction);
43.509 + return NULL;
43.510 + }
43.511 + if (!plover_transaction_update(transaction,pkgs,error))
43.512 + {
43.513 + g_object_unref(transaction);
43.514 + return NULL;
43.515 + }
43.516 + return transaction;
43.517 +}
43.518 +
43.519 +static int plover_mark_packages_for_removal(struct razor_transaction *trans,
43.520 + struct razor_set *set,const char *pkg)
43.521 +{
43.522 + struct razor_package_iterator *pi;
43.523 + struct razor_package *package;
43.524 + const char *name;
43.525 + int retval=pkg?-1:0;
43.526 + pi=razor_package_iterator_create(set);
43.527 + while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
43.528 + RAZOR_DETAIL_LAST))
43.529 + {
43.530 + if (!pkg || !strcmp(name,pkg))
43.531 + {
43.532 + razor_transaction_remove_package(trans,package);
43.533 + retval=0;
43.534 + }
43.535 + }
43.536 + razor_package_iterator_destroy(pi);
43.537 + return retval;
43.538 +}
43.539 +
43.540 +gboolean plover_transaction_remove(PloverTransaction *transaction,
43.541 + char **pkgs,GError **error)
43.542 +{
43.543 + int i;
43.544 + struct razor_set *system,*empty;
43.545 + g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
43.546 + g_return_val_if_fail(transaction->trans == NULL,FALSE);
43.547 + if (!plover_transaction_root_open(transaction,NULL,error))
43.548 + return FALSE;
43.549 + system=plover_transaction_get_system_set(transaction);
43.550 + if (!system)
43.551 + {
43.552 + g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
43.553 + "Internal error: No system set");
43.554 + return FALSE;
43.555 + }
43.556 + empty=razor_set_create_without_root();
43.557 + transaction->trans=razor_transaction_create(system,empty);
43.558 + razor_set_unref(empty);
43.559 + if (!pkgs)
43.560 + plover_mark_packages_for_removal(transaction->trans,system,NULL);
43.561 + else
43.562 + for(i=0;pkgs[i];i++)
43.563 + if (plover_mark_packages_for_removal(transaction->trans,system,
43.564 + pkgs[i]))
43.565 + {
43.566 + g_set_error(error,PLOVER_GENERAL_ERROR,
43.567 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,"%s: %s",pkgs[i],
43.568 + "Package not found");
43.569 + razor_transaction_destroy(transaction->trans);
43.570 + transaction->trans=NULL;
43.571 + return FALSE;
43.572 + break;
43.573 + }
43.574 + return TRUE;
43.575 +}
43.576 +
43.577 +PloverTransaction *plover_transaction_new_remove(char **pkgs,GError **error)
43.578 +{
43.579 + PloverTransaction *transaction;
43.580 + transaction=plover_transaction_new();
43.581 + if (!plover_transaction_remove(transaction,pkgs,error))
43.582 + {
43.583 + g_object_unref(transaction);
43.584 + return NULL;
43.585 + }
43.586 + return transaction;
43.587 +}
43.588 +
43.589 +static GList *plover_what_requires(struct razor_set *set,const char *ref_name)
43.590 +{
43.591 + const char *name,*version;
43.592 + uint32_t flags;
43.593 + GList *list=NULL;
43.594 + struct razor_property *property;
43.595 + struct razor_package *package;
43.596 + struct razor_package_iterator *what_requires;
43.597 + struct razor_property_iterator *all_props;
43.598 + all_props=razor_property_iterator_create(set,NULL);
43.599 + while (razor_property_iterator_next(all_props,&property,&name,&flags,
43.600 + &version))
43.601 + {
43.602 + if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=RAZOR_PROPERTY_REQUIRES)
43.603 + continue;
43.604 + if (strcmp(name,ref_name))
43.605 + continue;
43.606 + what_requires=razor_package_iterator_create_for_property(set,property);
43.607 + while(razor_package_iterator_next(what_requires,&package,
43.608 + RAZOR_DETAIL_LAST))
43.609 + list=g_list_prepend(list,package);
43.610 + razor_package_iterator_destroy(what_requires);
43.611 + }
43.612 + razor_property_iterator_destroy(all_props);
43.613 + return list;
43.614 +}
43.615 +
43.616 +/*
43.617 + * Warning: This code is untested and probably wrong.
43.618 + */
43.619 +PloverTransaction *plover_transaction_new_remove_with_leaves(char **pkgs,
43.620 + GError **error)
43.621 +{
43.622 + int i,changed,is_leaf;
43.623 + uint32_t flags;
43.624 + const char *install_root;
43.625 + const char *name,*version,*maybe_unused_name;
43.626 + struct razor_set *system,*upstream;
43.627 + struct razor_transaction *trans;
43.628 + PloverPackageSet *installed;
43.629 + PloverTransaction *transaction;
43.630 + if (!pkgs)
43.631 + return plover_transaction_new_remove(NULL,error);
43.632 + installed=plover_package_set_new();
43.633 + install_root=g_getenv("RAZOR_ROOT");
43.634 + if (!install_root)
43.635 + install_root="";
43.636 + if (!plover_package_set_open(installed,install_root,TRUE,error))
43.637 + {
43.638 + g_object_unref(installed);
43.639 + return NULL;
43.640 + }
43.641 + system=plover_package_set_get_razor(installed);
43.642 + struct plover_vector *package_names;
43.643 + GList *to_remove,*lnk,*what_requires;
43.644 + struct razor_package *package,*maybe_unused_package;
43.645 + struct razor_property *property;
43.646 + struct razor_package_query *query;
43.647 + struct razor_package_iterator *all_packages,*removed,*maybe_unused;
43.648 + struct razor_property_iterator *removed_props;
43.649 + package_names=plover_vector_new();
43.650 + for(i=0;pkgs[i];i++)
43.651 + plover_vector_append(package_names,pkgs[i]);
43.652 + to_remove=NULL;
43.653 + all_packages=razor_package_iterator_create(system);
43.654 + while (razor_package_iterator_next(all_packages,&package,
43.655 + RAZOR_DETAIL_NAME,&name,RAZOR_DETAIL_LAST))
43.656 + if (plover_vector_remove(package_names,name))
43.657 + to_remove=g_list_prepend(to_remove,package);
43.658 + razor_package_iterator_destroy(all_packages);
43.659 + if (package_names->len)
43.660 + {
43.661 + g_set_error(error,PLOVER_GENERAL_ERROR,
43.662 + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,"%s: %s",
43.663 + package_names->strings[0],"Package not found");
43.664 + plover_vector_free(package_names);
43.665 + g_list_free(to_remove);
43.666 + g_object_unref(installed);
43.667 + return NULL;
43.668 + }
43.669 + plover_vector_free(package_names);
43.670 + do
43.671 + {
43.672 + changed=FALSE;
43.673 + query=razor_package_query_create(system);
43.674 + for(lnk=to_remove;lnk;lnk=lnk->next)
43.675 + razor_package_query_add_package(query,lnk->data);
43.676 + removed=razor_package_query_finish(query);
43.677 + while(razor_package_iterator_next(removed,&package,RAZOR_DETAIL_LAST))
43.678 + {
43.679 + removed_props=razor_property_iterator_create(system,package);
43.680 + while (razor_property_iterator_next(removed_props,&property,&name,
43.681 + &flags,&version))
43.682 + {
43.683 + if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=RAZOR_PROPERTY_REQUIRES)
43.684 + continue;
43.685 + maybe_unused=razor_package_iterator_create_for_property(system,
43.686 + property);
43.687 + while(razor_package_iterator_next(maybe_unused,
43.688 + &maybe_unused_package,RAZOR_DETAIL_NAME,&maybe_unused_name,
43.689 + RAZOR_DETAIL_LAST))
43.690 + {
43.691 + if (g_list_find(to_remove,maybe_unused_package))
43.692 + continue;
43.693 + is_leaf=TRUE;
43.694 + what_requires=plover_what_requires(system,
43.695 + maybe_unused_name);
43.696 + for(lnk=what_requires;lnk;lnk=lnk->next)
43.697 + if (!g_list_find(to_remove,lnk->data))
43.698 + {
43.699 + is_leaf=FALSE;
43.700 + break;
43.701 + }
43.702 + g_list_free(what_requires);
43.703 + if (is_leaf)
43.704 + {
43.705 + to_remove=g_list_prepend(to_remove,
43.706 + maybe_unused_package);
43.707 + changed=TRUE;
43.708 + }
43.709 + }
43.710 + razor_package_iterator_destroy(maybe_unused);
43.711 + }
43.712 + razor_property_iterator_destroy(removed_props);
43.713 + }
43.714 + razor_package_iterator_destroy(removed);
43.715 + } while(changed);
43.716 + upstream=razor_set_create_without_root();
43.717 + trans=razor_transaction_create(system,upstream);
43.718 + razor_set_unref(upstream);
43.719 + for(lnk=to_remove;lnk;lnk=lnk->next)
43.720 + razor_transaction_remove_package(trans,lnk->data);
43.721 + transaction=plover_transaction_new();
43.722 + transaction->trans=trans;
43.723 + transaction->installed=installed;
43.724 + return transaction;
43.725 +}
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/plover/transaction.h Sat Nov 15 19:04:45 2014 +0000
44.3 @@ -0,0 +1,87 @@
44.4 +#ifndef __PLOVER_TRANSACTION_H__
44.5 +#define __PLOVER_TRANSACTION_H__
44.6 +
44.7 +#include <razor.h>
44.8 +#include <glib-object.h>
44.9 +#include <gio/gio.h>
44.10 +#include <plover/packageset.h>
44.11 +
44.12 +G_BEGIN_DECLS
44.13 +
44.14 +#define PLOVER_TYPE_TRANSACTION plover_transaction_get_type()
44.15 +#define PLOVER_TRANSACTION(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,\
44.16 + PLOVER_TYPE_TRANSACTION,\
44.17 + PloverTransaction)
44.18 +#define PLOVER_IS_TRANSACTION(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj,\
44.19 + PLOVER_TYPE_TRANSACTION)
44.20 +
44.21 +typedef enum {
44.22 + PLOVER_TRANSACTION_RESOLVED=1<<0,
44.23 + PLOVER_TRANSACTION_UNSATISFIED=1<<1,
44.24 +} PloverTransactionFlags;
44.25 +
44.26 +typedef struct _PloverTransaction {
44.27 + GObject parent_instance;
44.28 + PloverTransactionFlags flags;
44.29 + struct razor_transaction *trans;
44.30 + char *prefix;
44.31 + char *base;
44.32 + char *install_root;
44.33 + char *unsatisfied;
44.34 + PloverPackageSet *installed,*relocated;
44.35 + PloverRepository *upstream;
44.36 + struct razor_relocations *relocations;
44.37 + struct razor_set *next,*system;
44.38 + struct razor_install_iterator *install_iterator;
44.39 +} PloverTransaction;
44.40 +
44.41 +typedef struct _PloverTransactionClass {
44.42 + GObjectClass parent_class;
44.43 +} PloverTransactionClass;
44.44 +
44.45 +GType plover_transaction_get_type(void) G_GNUC_CONST;
44.46 +void plover_transaction_commit_async(PloverTransaction *transaction,
44.47 + GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data);
44.48 +gboolean plover_transaction_commit_finish(PloverTransaction *transaction,
44.49 + GAsyncResult *result,GError **error);
44.50 +PloverTransaction *plover_transaction_new();
44.51 +void plover_transaction_set_prefix(PloverTransaction *transaction,
44.52 + const char *prefix);
44.53 +void plover_transaction_set_installed(PloverTransaction *transaction,
44.54 + PloverPackageSet *installed);
44.55 +gboolean plover_transaction_root_open(PloverTransaction *transaction,
44.56 + const char *install_root,GError **error);
44.57 +struct razor_set *plover_transaction_import_yum(PloverTransaction *transaction,
44.58 + const char *base,GError **error);
44.59 +gboolean plover_transaction_set_upstream(PloverTransaction *transaction,
44.60 + PloverRepository *upstream,GError **error);
44.61 +gboolean
44.62 + plover_transaction_set_upstream_from_yum(PloverTransaction *transaction,
44.63 + const char *base,GError **error);
44.64 +gboolean plover_transaction_install(PloverTransaction *transaction,
44.65 + char **pkgs,GError **error);
44.66 +PloverTransaction *plover_transaction_new_install(const char *base,
44.67 + const char *prefix,char **pkgs,GError **error);
44.68 +gboolean plover_transaction_update(PloverTransaction *transaction,
44.69 + char **pkgs,GError **error);
44.70 +PloverTransaction *plover_transaction_new_update(const char *base,
44.71 + const char *prefix,char **pkgs,GError **error);
44.72 +gboolean plover_transaction_remove(PloverTransaction *transaction,
44.73 + char **pkgs,GError **error);
44.74 +PloverTransaction *plover_transaction_new_remove(char **pkgs,
44.75 + GError **error);
44.76 +gboolean plover_transaction_resolve(PloverTransaction *transaction,
44.77 + GError **error);
44.78 +const char *plover_transaction_get_unsatisfied(PloverTransaction *transaction);
44.79 +struct razor_set *plover_transaction_get_system_set(
44.80 + PloverTransaction *transaction);
44.81 +struct razor_set *plover_transaction_get_next_set(
44.82 + PloverTransaction *transaction,GError **error);
44.83 +struct razor_install_iterator *plover_transaction_get_install_iterator(
44.84 + PloverTransaction *transaction,GError **error);
44.85 +gboolean plover_transaction_commit(PloverTransaction *transaction,
44.86 + GCancellable *cancellable,GError **error);
44.87 +void plover_transaction_commit_async(PloverTransaction *transaction,
44.88 + GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data);
44.89 +
44.90 +#endif /* __PLOVER_TRANSACTION_H__ */
45.1 --- a/plover/util.c Fri Mar 23 20:29:50 2012 +0000
45.2 +++ b/plover/util.c Sat Nov 15 19:04:45 2014 +0000
45.3 @@ -1,5 +1,5 @@
45.4 /*
45.5 - * Copyright (C) 2009, 2011 J. Ali Harlow <ali@juiblex.co.uk>
45.6 + * Copyright (C) 2009, 2011, 2014 J. Ali Harlow <ali@juiblex.co.uk>
45.7 *
45.8 * This program is free software; you can redistribute it and/or modify
45.9 * it under the terms of the GNU General Public License as published by
45.10 @@ -27,37 +27,7 @@
45.11 #include "config.h"
45.12 #include "plover.h"
45.13
45.14 -char *plover_strconcat(const char *string,...)
45.15 -{
45.16 - va_list ap,aq;
45.17 - size_t n;
45.18 - char *result=NULL,*t;
45.19 - const char *s;
45.20 - if (string)
45.21 - {
45.22 - va_start(ap,string);
45.23 - va_copy(aq,ap);
45.24 - n=strlen(string);
45.25 - while((s=va_arg(aq,const char *)))
45.26 - n+=strlen(s);
45.27 - va_end(aq);
45.28 - result=malloc(n+1);
45.29 - if (result)
45.30 - {
45.31 - strcpy(result,string);
45.32 - t=result+strlen(result);
45.33 - while((s=va_arg(ap,const char *)))
45.34 - {
45.35 - strcpy(t,s);
45.36 - t+=strlen(t);
45.37 - }
45.38 - }
45.39 - va_end(ap);
45.40 - }
45.41 - return result;
45.42 -}
45.43 -
45.44 -char *plover_default_prefix_for_vendor(const char *vendor)
45.45 +gchar *plover_default_prefix_for_vendor(const char *vendor)
45.46 {
45.47 #ifdef WIN32
45.48 /*
45.49 @@ -83,12 +53,59 @@
45.50 buf);
45.51 program_files=buf;
45.52 }
45.53 - return plover_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL);
45.54 + return g_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL);
45.55 #else
45.56 return NULL;
45.57 #endif
45.58 }
45.59
45.60 +gchar *plover_pre_install_prefix(void)
45.61 +{
45.62 +#ifdef WIN32
45.63 + {
45.64 + HRESULT result;
45.65 + HKEY key;
45.66 + DWORD type,nb;
45.67 + int len;
45.68 + gunichar2 *str2;
45.69 + gchar *root=NULL;
45.70 + result=RegOpenKeyW(HKEY_LOCAL_MACHINE,L"Software\\Plover",&key);
45.71 + if (result==ERROR_SUCCESS)
45.72 + {
45.73 + result=RegQueryValueExW(key,L"Root",0,&type,0,&nb);
45.74 + if (result==ERROR_SUCCESS && type==REG_SZ)
45.75 + {
45.76 + str2=malloc(nb);
45.77 + result=RegQueryValueExW(key,L"Root",0,NULL,(void *)str2,&nb);
45.78 + len=nb/2;
45.79 + if (!str2[len-1]) /* Cope with unterminated strings */
45.80 + len--;
45.81 + root=g_utf16_to_utf8(str2,len,NULL,NULL,NULL);
45.82 + free(str2);
45.83 + }
45.84 + RegCloseKey(key);
45.85 + }
45.86 + if (!root)
45.87 + {
45.88 + root=plover_default_prefix_for_vendor("Plover Root");
45.89 + result=RegCreateKeyExW(HKEY_LOCAL_MACHINE,L"Software\\Plover",0,
45.90 + NULL,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&key,NULL);
45.91 + if (result==ERROR_SUCCESS)
45.92 + {
45.93 + str2=g_utf8_to_utf16(root,-1,NULL,NULL,NULL);
45.94 + RegSetValueExW(key,L"Root",0,REG_SZ,(void *)str2,
45.95 + (strlen(root)+1)*sizeof(gunichar2));
45.96 + g_free(str2);
45.97 + RegCloseKey(key);
45.98 + }
45.99 + }
45.100 + return root;
45.101 + }
45.102 +#else
45.103 + return g_strdup("/var/lib/plover/root");
45.104 +#endif
45.105 +}
45.106 +
45.107 /*
45.108 * Get the directory containing the program executable.
45.109 */
45.110 @@ -119,3 +136,80 @@
45.111 return strdup(".");
45.112 #endif
45.113 }
45.114 +
45.115 +G_DEFINE_QUARK(plover-razor-error-quark,plover_razor_error)
45.116 +G_DEFINE_QUARK(plover-mswin-error-quark,plover_mswin_error)
45.117 +G_DEFINE_QUARK(plover-posix-error-quark,plover_posix_error)
45.118 +G_DEFINE_QUARK(plover-zlib-error-quark,plover_zlib_error)
45.119 +
45.120 +void plover_propagate_razor_error_dup(GError **dest,struct razor_error *src)
45.121 +{
45.122 + GQuark domain;
45.123 + int code;
45.124 + if (dest)
45.125 + {
45.126 + code=razor_error_get_code(src);
45.127 + switch(razor_error_get_domain(src))
45.128 + {
45.129 + case RAZOR_GENERAL_ERROR:
45.130 + domain=PLOVER_RAZOR_ERROR;
45.131 + break;
45.132 + case RAZOR_POSIX_ERROR:
45.133 + domain=PLOVER_POSIX_ERROR;
45.134 + break;
45.135 + case RAZOR_MSWIN_ERROR:
45.136 + domain=PLOVER_MSWIN_ERROR;
45.137 + break;
45.138 + case RAZOR_ZLIB_ERROR:
45.139 + domain=PLOVER_ZLIB_ERROR;
45.140 + break;
45.141 + case PLOVER_GENERAL_ERROR:
45.142 + if (code==PLOVER_GENERAL_ERROR_CANCELLED)
45.143 + {
45.144 + domain=G_IO_ERROR;
45.145 + code=G_IO_ERROR_CANCELLED;
45.146 + break;
45.147 + }
45.148 + /* else fall though */
45.149 + default:
45.150 + domain=PLOVER_RAZOR_ERROR;
45.151 + code=RAZOR_GENERAL_ERROR_FAILED;
45.152 + }
45.153 + *dest=g_error_new_literal(domain,code,razor_error_get_msg(src));
45.154 + }
45.155 +}
45.156 +
45.157 +void plover_propagate_razor_error(GError **dest,struct razor_error *src)
45.158 +{
45.159 + plover_propagate_razor_error_dup(dest,src);
45.160 + razor_error_free(src);
45.161 +}
45.162 +
45.163 +void plover_propagate_g_error(struct razor_error **dest,GError *src)
45.164 +{
45.165 + int domain,code;
45.166 + if (dest)
45.167 + {
45.168 + code=src->code;
45.169 + if (src->domain==PLOVER_RAZOR_ERROR)
45.170 + domain=RAZOR_GENERAL_ERROR;
45.171 + else if (src->domain==PLOVER_POSIX_ERROR)
45.172 + domain=RAZOR_POSIX_ERROR;
45.173 + else if (src->domain==PLOVER_MSWIN_ERROR)
45.174 + domain=RAZOR_MSWIN_ERROR;
45.175 + else if (src->domain==PLOVER_ZLIB_ERROR)
45.176 + domain=RAZOR_ZLIB_ERROR;
45.177 + else if (src->domain==G_IO_ERROR && code==G_IO_ERROR_CANCELLED)
45.178 + {
45.179 + domain=PLOVER_GENERAL_ERROR;
45.180 + code=PLOVER_GENERAL_ERROR_CANCELLED;
45.181 + }
45.182 + else
45.183 + {
45.184 + domain=RAZOR_GENERAL_ERROR;
45.185 + code=RAZOR_GENERAL_ERROR_FAILED;
45.186 + }
45.187 + *dest=razor_error_new_str(domain,code,NULL,src->message);
45.188 + }
45.189 + g_error_free(src);
45.190 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/plover/vector.c Sat Nov 15 19:04:45 2014 +0000
46.3 @@ -0,0 +1,130 @@
46.4 +/*
46.5 + * Copyright (C) 2009, 2014 J. Ali Harlow <ali@juiblex.co.uk>
46.6 + *
46.7 + * This program is free software; you can redistribute it and/or modify
46.8 + * it under the terms of the GNU General Public License as published by
46.9 + * the Free Software Foundation; either version 2 of the License, or
46.10 + * (at your option) any later version.
46.11 + *
46.12 + * This program is distributed in the hope that it will be useful,
46.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
46.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46.15 + * GNU General Public License for more details.
46.16 + *
46.17 + * You should have received a copy of the GNU General Public License along
46.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
46.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
46.20 + */
46.21 +
46.22 +#include <stdlib.h>
46.23 +#include <string.h>
46.24 +#include "config.h"
46.25 +#include "plover.h"
46.26 +
46.27 +struct plover_vector *plover_vector_new(void)
46.28 +{
46.29 + struct plover_vector *vector;
46.30 + vector=malloc(sizeof(*vector));
46.31 + vector->len=0;
46.32 + vector->alloc=16;
46.33 + vector->strings=calloc(vector->alloc,sizeof(char *));
46.34 + return vector;
46.35 +}
46.36 +
46.37 +struct plover_vector *plover_vector_dup(struct plover_vector *old)
46.38 +{
46.39 + int i;
46.40 + struct plover_vector *vector;
46.41 + vector=malloc(sizeof(*vector));
46.42 + vector->len=old->len;
46.43 + vector->alloc=old->alloc;
46.44 + vector->strings=calloc(vector->alloc,sizeof(char *));
46.45 + for(i=0;i<old->len;i++)
46.46 + vector->strings[i]=strdup(old->strings[i]);
46.47 + vector->strings[i]=NULL;
46.48 + return vector;
46.49 +}
46.50 +
46.51 +void plover_vector_append(struct plover_vector *vector,const char *str)
46.52 +{
46.53 + if (++(vector->len)>=vector->alloc)
46.54 + {
46.55 + vector->alloc*=2;
46.56 + vector->strings=realloc(vector->strings,vector->alloc*sizeof(char *));
46.57 + }
46.58 + vector->strings[vector->len-1]=strdup(str);
46.59 + vector->strings[vector->len]=NULL;
46.60 +}
46.61 +
46.62 +int plover_vector_contains(struct plover_vector *vector,const char *str)
46.63 +{
46.64 + int i;
46.65 + for(i=0;i<vector->len;i++)
46.66 + if (!strcmp(vector->strings[i],str))
46.67 + return 1;
46.68 + return 0;
46.69 +}
46.70 +
46.71 +int plover_vector_remove(struct plover_vector *vector,const char *str)
46.72 +{
46.73 + int i;
46.74 + for(i=0;i<vector->len;i++)
46.75 + if (!strcmp(vector->strings[i],str))
46.76 + {
46.77 + free(vector->strings[i]);
46.78 + vector->len--;
46.79 + vector->strings[i]=vector->strings[vector->len];
46.80 + vector->strings[vector->len]=NULL;
46.81 + return 1;
46.82 + }
46.83 + return 0;
46.84 +}
46.85 +
46.86 +static int string_compar(const void *p1,const void *p2)
46.87 +{
46.88 + return strcmp(*(char * const *)p1,*(char * const *)p2);
46.89 +}
46.90 +
46.91 +void plover_vector_sort(struct plover_vector *vector)
46.92 +{
46.93 + qsort(vector->strings,vector->len,sizeof(char *),string_compar);
46.94 +}
46.95 +
46.96 +char *plover_vector_format_for_display(struct plover_vector *vector)
46.97 +{
46.98 + int i,len;
46.99 + char *s,*p;
46.100 + if (!vector->len)
46.101 + return strdup("none");
46.102 + else if (vector->len==1)
46.103 + return strdup(vector->strings[0]);
46.104 + else
46.105 + {
46.106 + len=(vector->len-1)*2+5+1;
46.107 + for(i=0;i<vector->len;i++)
46.108 + len+=strlen(vector->strings[i]);
46.109 + s=malloc(len);
46.110 + strcpy(s,vector->strings[0]);
46.111 + p=s+strlen(s);
46.112 + for(i=1;i<vector->len-1;i++)
46.113 + {
46.114 + *p++=',';
46.115 + *p++=' ';
46.116 + strcpy(p,vector->strings[i]);
46.117 + p+=strlen(p);
46.118 + }
46.119 + strcpy(p," and ");
46.120 + p+=5;
46.121 + strcpy(p,vector->strings[i]);
46.122 + return s;
46.123 + }
46.124 +}
46.125 +
46.126 +void plover_vector_free(struct plover_vector *vector)
46.127 +{
46.128 + int i;
46.129 + for(i=0;i<vector->len;i++)
46.130 + free(vector->strings[i]);
46.131 + free(vector->strings);
46.132 + free(vector);
46.133 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/pre-inst/Makefile.am Sat Nov 15 19:04:45 2014 +0000
47.3 @@ -0,0 +1,32 @@
47.4 +AM_CFLAGS=-g $(SETUP_CFLAGS)
47.5 +LDADD=../plover/libplover.la $(SETUP_LIBS)
47.6 +if PLOVER_MINGW
47.7 +LDADD+=-lcomctl32
47.8 +# pre-inst is not intended to produce any output (and any that is produced
47.9 +# can be safely junked). Thus -mwindows is appropriate since if called with
47.10 +# a console window attached no output should be visible anyway and if called
47.11 +# when no console window is attached we don't want one to be created.
47.12 +AM_LDFLAGS=-mwindows
47.13 +endif
47.14 +INCLUDES=-I$(top_srcdir) -I$(srcdir)
47.15 +
47.16 +bin_PROGRAMS=pre-inst
47.17 +
47.18 +pre_inst_SOURCES=pre-inst.c
47.19 +pre_inst_LDFLAGS=$(AM_LDFLAGS) -all-static
47.20 +if HAVE_WINDRES
47.21 +pre_inst_SOURCES+=resources.rc pre-inst.exe.manifest resource.h
47.22 +endif
47.23 +
47.24 +.rc.$(OBJEXT):
47.25 + $(AM_V_GEN)$(WINDRES) $(INCLUDES) $< $@
47.26 +
47.27 +resources.$(OBJEXT): resources.rc resource.h pre-inst.exe.manifest pre-inst.ico
47.28 +
47.29 +.png.pnm:
47.30 + $(AM_V_GEN)pngtopnm $< | pnmquant -quiet 256 > $@
47.31 +
47.32 +pre-inst.ico: icon16.pnm icon22.pnm icon32.pnm
47.33 + $(AM_V_GEN)ppmtowinicon -output=$@ $^
47.34 +
47.35 +EXTRA_DIST=icon16.png icon22.png icon32.png
48.1 Binary file pre-inst/icon16.png has changed
49.1 Binary file pre-inst/icon22.png has changed
50.1 Binary file pre-inst/icon32.png has changed
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/pre-inst/manifest.xml.in Sat Nov 15 19:04:45 2014 +0000
51.3 @@ -0,0 +1,29 @@
51.4 +changequote([,])dnl
51.5 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
51.6 +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
51.7 + <assemblyIdentity
51.8 + version="@PLOVER_MAJOR_VERSION@.@PLOVER_MINOR_VERSION@.@PLOVER_MICRO_VERSION@.0"
51.9 + name="The plover development team.plover.pre-inst" type="win32"
51.10 + processorArchitecture="ifelse([@HOST_CPU@],[x86_64],[ia64],[x86])" />
51.11 + <description>Plover pre-inst program</description>
51.12 + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
51.13 + <application>
51.14 + <!-- Windows 7 functionality -->
51.15 + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
51.16 + </application>
51.17 + </compatibility>
51.18 + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
51.19 + <security>
51.20 + <requestedPrivileges>
51.21 + <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
51.22 + </requestedPrivileges>
51.23 + </security>
51.24 + </trustInfo>
51.25 + <dependency>
51.26 + <dependentAssembly>
51.27 + <assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls"
51.28 + version="6.0.0.0" processorArchitecture="*"
51.29 + publicKeyToken="6595b64144ccf1df" language="*"/>
51.30 + </dependentAssembly>
51.31 + </dependency>
51.32 +</assembly>
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/pre-inst/pre-inst.c Sat Nov 15 19:04:45 2014 +0000
52.3 @@ -0,0 +1,504 @@
52.4 +/*
52.5 + * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
52.6 + *
52.7 + * This program is free software; you can redistribute it and/or modify
52.8 + * it under the terms of the GNU General Public License as published by
52.9 + * the Free Software Foundation; either version 2 of the License, or
52.10 + * (at your option) any later version.
52.11 + *
52.12 + * This program is distributed in the hope that it will be useful,
52.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
52.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52.15 + * GNU General Public License for more details.
52.16 + *
52.17 + * You should have received a copy of the GNU General Public License along
52.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
52.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
52.20 + *
52.21 + * References:
52.22 + * http://www.transmissionzero.co.uk/computing/win32-apps-with-mingw/
52.23 + */
52.24 +
52.25 +#include "config.h"
52.26 +#ifndef WIN32
52.27 +#define _XOPEN_SOURCE 500
52.28 +#endif
52.29 +#include <stdlib.h>
52.30 +#include <stdio.h>
52.31 +#include <string.h>
52.32 +#include <lua.h>
52.33 +#include <razor.h>
52.34 +#include <plover/plover.h>
52.35 +#include <whelk/whelk.h>
52.36 +#ifdef WIN32
52.37 +#include <windows.h>
52.38 +#include <process.h>
52.39 +#include <commctrl.h>
52.40 +#include "resource.h"
52.41 +
52.42 +#ifndef FOF_NO_UI
52.43 +#define FOF_NO_UI (FOF_SILENT|FOF_NOCONFIRMATION|FOF_NOERRORUI|\
52.44 + FOF_NOCONFIRMMKDIR)
52.45 +#endif
52.46 +
52.47 +#else /* WIN32 */
52.48 +#include <ftw.h>
52.49 +#endif /* WIN32 */
52.50 +
52.51 +#ifdef WIN32
52.52 +/* Under WIN32, g_spawn requires a helper program which we'd rather avoid */
52.53 +#undef USE_G_SPAWN
52.54 +#else
52.55 +#define USE_G_SPAWN
52.56 +#endif
52.57 +
52.58 +LUALIB_API int luaopen_posix(lua_State *L);
52.59 +
52.60 +#ifdef WIN32
52.61 +DWORD main_thread_id;
52.62 +#endif
52.63 +
52.64 +gchar *prefix;
52.65 +
52.66 +int verify_and_fix(const char *root)
52.67 +{
52.68 + return 0;
52.69 +}
52.70 +
52.71 +#ifdef WIN32
52.72 +INT_PTR CALLBACK ProgressDialogProc(HWND dialog,UINT msg,WPARAM w_param,
52.73 + LPARAM l_param)
52.74 +{
52.75 + HWND progress;
52.76 + DWORD style;
52.77 + switch (msg)
52.78 + {
52.79 + case WM_INITDIALOG:
52.80 + progress=GetDlgItem(dialog,IDC_PROGRESS);
52.81 + style=GetWindowLong(progress,GWL_STYLE);
52.82 + SetWindowLong(progress,GWL_STYLE,style|PBS_MARQUEE);
52.83 + SendMessage(progress,PBM_SETMARQUEE,(WPARAM)TRUE,(LPARAM)30);
52.84 + return (INT_PTR)TRUE;
52.85 + }
52.86 + return (INT_PTR)FALSE;
52.87 +}
52.88 +#endif
52.89 +
52.90 +#ifdef WIN32
52.91 +__stdcall
52.92 +#endif
52.93 +unsigned pre_install_thread(void *data)
52.94 +{
52.95 + int retval;
52.96 + char *path=data;
52.97 + gchar *s;
52.98 + char *install[]={"plover-gtkui",NULL};
52.99 + GError *error=NULL;
52.100 + prefix=plover_pre_install_prefix();
52.101 + s=g_strconcat(prefix,"/var/log/pre-install",NULL);
52.102 + plover_log_open(s);
52.103 + g_free(s);
52.104 + s=g_strconcat(prefix,"/var/lib/razor",NULL);
52.105 + razor_set_database_path(s);
52.106 + g_free(s);
52.107 + if (verify_and_fix(prefix))
52.108 + {
52.109 + free(path);
52.110 + g_free(prefix);
52.111 + return -1;
52.112 + }
52.113 + retval=!plover_install(path,prefix,install,&error);
52.114 + if (!retval)
52.115 + retval=!plover_update(path,prefix,NULL,&error);
52.116 + if (error)
52.117 + {
52.118 + fprintf(stderr,"%s\n",error->message);
52.119 + g_error_free(error);
52.120 + }
52.121 + free(path);
52.122 +#ifdef WIN32
52.123 + PostQuitMessage(retval);
52.124 + PostThreadMessage(main_thread_id,WM_QUIT,retval,0);
52.125 + _endthreadex(retval);
52.126 +#endif
52.127 + return retval;
52.128 +}
52.129 +
52.130 +/*
52.131 + * The idea is that if pre_install() fails, update/setup should fall back
52.132 + * to console interfaces.
52.133 + */
52.134 +#ifdef WIN32
52.135 +HANDLE
52.136 +#else
52.137 +void *
52.138 +#endif
52.139 +pre_install(const char *argv0)
52.140 +{
52.141 +#ifdef WIN32
52.142 + HANDLE retval;
52.143 +#else
52.144 + void *retval;
52.145 +#endif
52.146 + char *path;
52.147 + razor_set_lua_loader("posix",luaopen_posix);
52.148 + razor_set_lua_loader("whelk",luaopen_whelk);
52.149 + path=plover_get_program_directory(argv0);
52.150 +#ifdef WIN32
52.151 + retval=(HANDLE)_beginthreadex(NULL,0,pre_install_thread,path,0,NULL);
52.152 +#else
52.153 + if (pre_install_thread(path))
52.154 + retval=NULL;
52.155 + else
52.156 + retval=(void *)1; /* Non-NULL to indicate success */
52.157 +#endif
52.158 + return retval;
52.159 +}
52.160 +
52.161 +#ifndef WIN32
52.162 +int remove_ignore(const char *fpath,const struct stat *sb,int typeflag,
52.163 + struct FTW *ftwbuf)
52.164 +{
52.165 + (void)remove(fpath);
52.166 + return 0;
52.167 +}
52.168 +#endif
52.169 +
52.170 +gboolean deltree(const char *path)
52.171 +{
52.172 +#ifdef WIN32
52.173 + /* Based on g_local_file_trash() */
52.174 + SHFILEOPSTRUCTW op={0};
52.175 + gboolean success;
52.176 + wchar_t *wfilename;
52.177 + long len;
52.178 + wfilename=g_utf8_to_utf16(path,-1,NULL,&len,NULL);
52.179 + /* SHFILEOPSTRUCT.pFrom is double-zero-terminated */
52.180 + wfilename=g_renew(wchar_t,wfilename,len+2);
52.181 + wfilename[len+1]=0;
52.182 + op.wFunc=FO_DELETE;
52.183 + op.pFrom=wfilename;
52.184 + op.fFlags=FOF_NO_UI;
52.185 + success=!SHFileOperationW(&op);
52.186 + if (success && op.fAnyOperationsAborted)
52.187 + success=FALSE;
52.188 + g_free(wfilename);
52.189 + return success;
52.190 +#else
52.191 + return nftw(path,remove_ignore,64,FTW_DEPTH|FTW_PHYS);
52.192 +#endif
52.193 +}
52.194 +
52.195 +gboolean pre_uninstall(void)
52.196 +{
52.197 + gboolean success;
52.198 + gchar *s;
52.199 + GError *error=NULL;
52.200 + razor_set_lua_loader("posix",luaopen_posix);
52.201 + razor_set_lua_loader("whelk",luaopen_whelk);
52.202 + prefix=plover_pre_install_prefix();
52.203 + s=g_strconcat(prefix,"/var/lib/razor",NULL);
52.204 + razor_set_database_path(s);
52.205 + g_free(s);
52.206 + success=plover_remove(NULL,&error);
52.207 + if (error)
52.208 + {
52.209 + fprintf(stderr,"%s\n",error->message);
52.210 + g_error_free(error);
52.211 + }
52.212 + deltree(prefix);
52.213 + return success;
52.214 +}
52.215 +
52.216 +#if defined(WIN32) && !defined(USE_G_SPAWN)
52.217 +/* Based on glib's g_spawn_win32.c */
52.218 +
52.219 +static gchar *
52.220 +win32_cmdline_quote(const char *string)
52.221 +{
52.222 + const gchar *p=string;
52.223 + gchar *retval,*q;
52.224 + gint len=0;
52.225 + gboolean need_dblquotes=FALSE;
52.226 + while (*p)
52.227 + {
52.228 + if (*p==' ' || *p=='\t')
52.229 + need_dblquotes=TRUE;
52.230 + else if (*p=='"')
52.231 + len++;
52.232 + else if (*p=='\\')
52.233 + {
52.234 + const gchar *pp=p;
52.235 + while (*pp && *pp=='\\')
52.236 + pp++;
52.237 + if (*pp=='"')
52.238 + len++;
52.239 + }
52.240 + len++;
52.241 + p++;
52.242 + }
52.243 + q=retval=g_malloc(len+need_dblquotes*2+1);
52.244 + p=string;
52.245 + if (need_dblquotes)
52.246 + *q++='"';
52.247 + while (*p)
52.248 + {
52.249 + if (*p=='"')
52.250 + *q++='\\';
52.251 + else if (*p=='\\')
52.252 + {
52.253 + const gchar *pp=p;
52.254 + while (*pp && *pp=='\\')
52.255 + pp++;
52.256 + if (*pp=='"')
52.257 + *q++='\\';
52.258 + }
52.259 + *q++=*p;
52.260 + p++;
52.261 + }
52.262 + if (need_dblquotes)
52.263 + *q++='"';
52.264 + *q++='\0';
52.265 + return retval;
52.266 +}
52.267 +
52.268 +/* Create a win32-style wide-character argv with suitable quoting */
52.269 +wchar_t **win32_argv_import(char **argv,GError **error)
52.270 +{
52.271 + int i,n;
52.272 + gchar *s;
52.273 + wchar_t **wargv;
52.274 + GError *tmp_error=NULL;
52.275 + n=g_strv_length(argv);
52.276 + wargv=g_new(wchar_t *,n+1);
52.277 + for(i=0;i<n;i++)
52.278 + {
52.279 + s=win32_cmdline_quote(argv[i]);
52.280 + wargv[i]=g_utf8_to_utf16(s,-1,NULL,NULL,&tmp_error);
52.281 + g_free(s);
52.282 + if (!wargv[i])
52.283 + {
52.284 + g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
52.285 + "Invalid argument #%d: %s",i,tmp_error->message);
52.286 + g_error_free(tmp_error);
52.287 + for(i--;i>=0;i--)
52.288 + g_free(wargv[i]);
52.289 + g_free(wargv);
52.290 + return FALSE;
52.291 + }
52.292 + }
52.293 + wargv[i]=NULL;
52.294 + return wargv;
52.295 +}
52.296 +
52.297 +gboolean spawn_sync(char **argv,GError **error)
52.298 +{
52.299 + wchar_t *wargv0,**wargv;
52.300 + gintptr rc;
52.301 + GError *tmp_error=NULL;
52.302 + wargv0=g_utf8_to_utf16(argv[0],-1,NULL,NULL,&tmp_error);
52.303 + if (!wargv0)
52.304 + {
52.305 + fprintf(stderr,"Conversion error in post\n");
52.306 + g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
52.307 + "Invalid program name: %s",tmp_error->message);
52.308 + g_error_free(tmp_error);
52.309 + return FALSE;
52.310 + }
52.311 + wargv=win32_argv_import(argv,error);
52.312 + if (!wargv)
52.313 + {
52.314 + fprintf(stderr,"Conversion error in post\n");
52.315 + g_free(wargv0);
52.316 + return FALSE;
52.317 + }
52.318 + errno=0;
52.319 + rc=_wspawnvp(P_WAIT,wargv0,(const wchar_t **)wargv);
52.320 + g_free(wargv0);
52.321 + g_strfreev((gchar **)wargv);
52.322 + if (rc==-1 && errno!=0)
52.323 + {
52.324 + fprintf(stderr,"Failed to start post command (%s)\n",g_strerror(errno));
52.325 + g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
52.326 + "Failed to execute post command: %s",g_strerror(errno));
52.327 + return FALSE;
52.328 + }
52.329 + if (rc!=EXIT_SUCCESS)
52.330 + {
52.331 + fprintf(stderr,"post command failed (%ld)\n",(long)rc);
52.332 + g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
52.333 + "Post command exited with code %ld",(long)rc);
52.334 + return FALSE;
52.335 + }
52.336 + return TRUE;
52.337 +}
52.338 +
52.339 +#endif /* defined(WIN32) && !defined(USE_G_SPAWN) */
52.340 +
52.341 +/*
52.342 + * Run a command after completing request.
52.343 + *
52.344 + * Command may refer to %INSTALL_PREFIX% which will be replaced by the
52.345 + * (first) install prefix used and/or %TEST_RESULT% which will be replaced
52.346 + * bu either "pass" or "fail" depending as to whether the request succeeded
52.347 + * or not. Command may also include double quotes which will be used to
52.348 + * affect how the command is split into arguments much like a shell does.
52.349 + */
52.350 +gboolean run_post(int argc,char **argv,gboolean test_result,GError **error)
52.351 +{
52.352 + int i,post_argc;
52.353 + char *s;
52.354 + gchar *expanded;
52.355 + gchar **post_argv;
52.356 +#ifdef USE_G_SPAWN
52.357 + gchar *standard_output,*standard_error;
52.358 + int exit_status;
52.359 +#endif
52.360 + GError *tmp_error=NULL;
52.361 + if (argc<1)
52.362 + {
52.363 + g_set_error_literal(error,G_FILE_ERROR,G_FILE_ERROR_NOENT,
52.364 + "--post: No command given");
52.365 + return FALSE;
52.366 + }
52.367 + printf("Running post command: %s\n",argv[1]);
52.368 + if (!g_shell_parse_argv(argv[1],&post_argc,&post_argv,&tmp_error))
52.369 + {
52.370 + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[1]);
52.371 + return FALSE;
52.372 + }
52.373 + for(i=0;i<post_argc;i++)
52.374 + {
52.375 + s=strstr(post_argv[i],"%INSTALL_PREFIX%");
52.376 + if (s)
52.377 + {
52.378 + *s='\0';
52.379 + s+=strlen("%INSTALL_PREFIX%");
52.380 + expanded=g_strconcat(post_argv[i],prefix,s,NULL);
52.381 + g_free(post_argv[i]);
52.382 + post_argv[i]=expanded;
52.383 + }
52.384 + s=strstr(post_argv[i],"%TEST_RESULT%");
52.385 + if (s)
52.386 + {
52.387 + *s='\0';
52.388 + s+=strlen("%TEST_RESULT%");
52.389 + expanded=g_strconcat(post_argv[i],test_result?"pass":"fail",s,NULL);
52.390 + g_free(post_argv[i]);
52.391 + post_argv[i]=expanded;
52.392 + }
52.393 + }
52.394 +#ifdef USE_G_SPAWN
52.395 + if (!g_spawn_sync(NULL,post_argv,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL,
52.396 + &standard_output,&standard_error,&exit_status,&tmp_error))
52.397 + {
52.398 + fprintf(stderr,"Failed to start post command\n");
52.399 + g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
52.400 + return FALSE;
52.401 + }
52.402 + if (standard_output && *standard_output)
52.403 + {
52.404 + printf("Output from post command %s:\n",post_argv[0]);
52.405 + fputs(standard_output,stdout);
52.406 + }
52.407 + g_free(standard_output);
52.408 + if (standard_error && *standard_error)
52.409 + {
52.410 + printf("Error output from post command %s:\n",post_argv[0]);
52.411 + fputs(standard_error,stdout);
52.412 + }
52.413 + g_free(standard_error);
52.414 + if (!g_spawn_check_exit_status(exit_status,&tmp_error))
52.415 + {
52.416 + fprintf(stderr,"post command failed\n");
52.417 + g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
52.418 + return FALSE;
52.419 + }
52.420 +#else
52.421 + if (!spawn_sync(post_argv,&tmp_error))
52.422 + {
52.423 + g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
52.424 + return FALSE;
52.425 + }
52.426 +#endif
52.427 + return TRUE;
52.428 +}
52.429 +
52.430 +#ifdef WIN32
52.431 +DWORD win32_pre_install_gui(char *argv0)
52.432 +{
52.433 + HANDLE thread;
52.434 + INITCOMMONCONTROLSEX icc={0,};
52.435 + MSG msg;
52.436 + DWORD retval;
52.437 + main_thread_id=GetCurrentThreadId();
52.438 + thread=(HANDLE)pre_install(argv0);
52.439 + if (!thread)
52.440 + return EXIT_FAILURE;
52.441 + icc.dwSize=sizeof(icc);
52.442 + icc.dwICC=ICC_WIN95_CLASSES;
52.443 + InitCommonControlsEx(&icc);
52.444 + DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PROGRESSDIALOG),NULL,
52.445 + &ProgressDialogProc);
52.446 + while(GetMessage(&msg,NULL,0,0)>0)
52.447 + {
52.448 + TranslateMessage(&msg);
52.449 + DispatchMessage(&msg);
52.450 + }
52.451 + WaitForSingleObject(thread,INFINITE);
52.452 + GetExitCodeThread(thread,&retval);
52.453 + CloseHandle(thread);
52.454 + return retval;
52.455 +}
52.456 +#endif /* WIN32 */
52.457 +
52.458 +int main(int argc,char **argv)
52.459 +{
52.460 + gboolean success;
52.461 + GError *error=NULL;
52.462 +#ifdef WIN32
52.463 + /*
52.464 + * pre-inst is normally a GUI application, but rpm scripts may well
52.465 + * call console applications and it looks ugly if console windows keep
52.466 + * popping up. Avoid this by allocating our own console and hiding it.
52.467 + * Note:
52.468 + * - If pre-inst is a console application (typically for debugging),
52.469 + * then skip this step.
52.470 + * - Call ShowWindow twice to negate special handling on first call.
52.471 + */
52.472 + if (!GetConsoleWindow())
52.473 + {
52.474 + AllocConsole();
52.475 + ShowWindow(GetConsoleWindow(),SW_HIDE);
52.476 + ShowWindow(GetConsoleWindow(),SW_HIDE);
52.477 + }
52.478 +#endif
52.479 + if (argc>1 && !strcmp(argv[1],"-u"))
52.480 + {
52.481 + success=pre_uninstall();
52.482 + argc--;
52.483 + argv++;
52.484 + }
52.485 + else
52.486 +#ifdef WIN32
52.487 + success=win32_pre_install_gui(argv[0])==EXIT_SUCCESS;
52.488 +#else
52.489 + success=!!pre_install(argv[0]);
52.490 +#endif
52.491 + if (argc>1 && !strcmp(argv[1],"--post") &&
52.492 + !run_post(argc-1,argv+1,success,&error))
52.493 + {
52.494 +#ifndef WIN32
52.495 + fprintf(stderr,"Error in post: %s\n",error->message);
52.496 +#else
52.497 + MessageBox(NULL,error->message,"Error in post",MB_ICONERROR|MB_OK);
52.498 +#endif
52.499 + g_error_free(error);
52.500 + success=FALSE;
52.501 + }
52.502 +#ifdef WIN32
52.503 + return success?EXIT_SUCCESS:EXIT_FAILURE;
52.504 +#else
52.505 + return success?0:1;
52.506 +#endif
52.507 +}
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/pre-inst/resource.h Sat Nov 15 19:04:45 2014 +0000
53.3 @@ -0,0 +1,6 @@
53.4 +#define IDD_PROGRESSDIALOG 100
53.5 +#define IDC_PROGRESS 1000
53.6 +
53.7 +#ifndef IDC_STATIC
53.8 +#define IDC_STATIC -1
53.9 +#endif
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/pre-inst/resources.rc.in Sat Nov 15 19:04:45 2014 +0000
54.3 @@ -0,0 +1,47 @@
54.4 +#include <windows.h>
54.5 +#include "resource.h"
54.6 +
54.7 +#pragma code_page(65001)
54.8 +
54.9 +MAINICON ICON "pre-inst.ico"
54.10 +
54.11 +VS_VERSION_INFO VERSIONINFO
54.12 + FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
54.13 + @PLOVER_MICRO_VERSION@,0
54.14 + PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
54.15 + @PLOVER_MICRO_VERSION@,0
54.16 + FILEOS VOS__WINDOWS32
54.17 + FILETYPE VFT_APP
54.18 + {
54.19 + BLOCK "StringFileInfo"
54.20 + {
54.21 + BLOCK "080904B0"
54.22 + {
54.23 + VALUE "CompanyName","The plover development team"
54.24 + VALUE "FileDescription","Plover pre-inst program"
54.25 + VALUE "FileVersion","@PACKAGE_VERSION@"
54.26 + VALUE "InternalName","pre-inst"
54.27 + VALUE "LegalCopyright",
54.28 + "Copyright © 2014 J. Ali Harlow et al"
54.29 + VALUE "OriginalFilename","pre-inst.exe"
54.30 + VALUE "ProductName","plover"
54.31 + VALUE "ProductVersion","@PACKAGE_VERSION@"
54.32 + }
54.33 + }
54.34 + BLOCK "VarFileInfo"
54.35 + {
54.36 + VALUE "Translation",0x809,0x4B0
54.37 + }
54.38 + }
54.39 +
54.40 +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "pre-inst.exe.manifest"
54.41 +
54.42 +IDD_PROGRESSDIALOG DIALOGEX 0,0,167,67
54.43 + STYLE DS_SETFONT|DS_MODALFRAME|DS_FIXEDSYS|WS_POPUP|WS_CAPTION
54.44 + CAPTION "Preparing to install..."
54.45 + FONT 8,"MS Shell Dlg",400,0,0x1
54.46 + {
54.47 + ICON MAINICON,IDC_STATIC,10,17,20,20
54.48 + LTEXT "Unpacking installation program.",IDC_STATIC,45,16,106,8
54.49 + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,45,28,106,8
54.50 + }
55.1 --- a/setup/Makefile.am Fri Mar 23 20:29:50 2012 +0000
55.2 +++ b/setup/Makefile.am Sat Nov 15 19:04:45 2014 +0000
55.3 @@ -3,6 +3,7 @@
55.4 INCLUDES=-I$(top_srcdir)
55.5
55.6 bin_PROGRAMS=setup
55.7 +bin_SCRIPTS=setup.js
55.8
55.9 setup_SOURCES=setup.c
55.10 setup_LDFLAGS=-all-static
55.11 @@ -10,13 +11,19 @@
55.12 setup_SOURCES+=resources.rc setup.exe.manifest
55.13 endif
55.14
55.15 -.png.pnm:
55.16 - pngtopnm $< | pnmquant 256 > $@
55.17 +.rc.$(OBJEXT):
55.18 + $(AM_V_GEN)$(WINDRES) resources.rc $@
55.19
55.20 resources.$(OBJEXT): resources.rc setup.exe.manifest setup.ico
55.21 - $(WINDRES) resources.rc $@
55.22 +
55.23 +%.js: $(srcdir)/%.js.in
55.24 + $(AM_V_GEN)sed -e 's/$$/\r/' $(srcdir)/$@.in > $@
55.25 +
55.26 +.png.pnm:
55.27 + $(AM_V_GEN)pngtopnm $< | pnmquant -quiet 256 > $@
55.28
55.29 setup.ico: icon16.pnm icon22.pnm icon32.pnm
55.30 - ppmtowinicon -output=$@ $^
55.31 + $(AM_V_GEN)ppmtowinicon -output=$@ $^
55.32
55.33 -EXTRA_DIST=icon16.png icon22.png icon32.png
55.34 +EXTRA_DIST=icon16.png icon22.png icon32.png setup.js.in
55.35 +CLEANFILES=setup.js
56.1 --- a/setup/resources.rc.in Fri Mar 23 20:29:50 2012 +0000
56.2 +++ b/setup/resources.rc.in Sat Nov 15 19:04:45 2014 +0000
56.3 @@ -1,6 +1,8 @@
56.4 #include <winver.h>
56.5 #include <winuser.h>
56.6
56.7 +#pragma code_page(65001)
56.8 +
56.9 MAINICON ICON "setup.ico"
56.10
56.11 VS_VERSION_INFO VERSIONINFO
56.12 @@ -20,7 +22,7 @@
56.13 VALUE "FileVersion","@PACKAGE_VERSION@"
56.14 VALUE "InternalName","setup"
56.15 VALUE "LegalCopyright",
56.16 - "Copyright (c) 2009,2011,2012 J. Ali Harlow et al"
56.17 + "Copyright © 2009,2011,2012 J. Ali Harlow et al"
56.18 VALUE "OriginalFilename","setup.exe"
56.19 VALUE "ProductName","plover"
56.20 VALUE "ProductVersion","@PACKAGE_VERSION@"
57.1 --- a/setup/setup.c Fri Mar 23 20:29:50 2012 +0000
57.2 +++ b/setup/setup.c Sat Nov 15 19:04:45 2014 +0000
57.3 @@ -31,67 +31,25 @@
57.4
57.5 LUALIB_API int luaopen_posix(lua_State *L);
57.6
57.7 -struct vector {
57.8 - int len,alloc;
57.9 - char **strings;
57.10 -};
57.11 -
57.12 -struct vector *vector_new(void)
57.13 -{
57.14 - struct vector *vector;
57.15 - vector=malloc(sizeof(*vector));
57.16 - vector->len=0;
57.17 - vector->alloc=16;
57.18 - vector->strings=calloc(vector->alloc,sizeof(char *));
57.19 - return vector;
57.20 -}
57.21 -
57.22 -void vector_append(struct vector *vector,const char *str)
57.23 -{
57.24 - if (++(vector->len)>=vector->alloc)
57.25 - {
57.26 - vector->alloc*=2;
57.27 - vector->strings=realloc(vector->strings,vector->alloc*sizeof(char *));
57.28 - }
57.29 - vector->strings[vector->len-1]=strdup(str);
57.30 - vector->strings[vector->len]=NULL;
57.31 -}
57.32 -
57.33 -int vector_contains(struct vector *vector,const char *str)
57.34 -{
57.35 - int i;
57.36 - for(i=0;i<vector->len;i++)
57.37 - if (!strcmp(vector->strings[i],str))
57.38 - return 1;
57.39 - return 0;
57.40 -}
57.41 -
57.42 -void vector_free(struct vector *vector)
57.43 -{
57.44 - int i;
57.45 - for(i=0;i<vector->len;i++)
57.46 - free(vector->strings[i]);
57.47 - free(vector->strings);
57.48 - free(vector);
57.49 -}
57.50 -
57.51 void setup(const char *argv0)
57.52 {
57.53 - char *path,*s,*prefix;
57.54 + char *path;
57.55 + gchar *s,*prefix;
57.56 int ch,changed;
57.57 struct comps *comps;
57.58 struct comps_group *group;
57.59 struct comps_requirement *pkg;
57.60 - struct vector *packages=NULL;
57.61 + struct plover_vector *packages=NULL;
57.62 + GError *error=NULL;
57.63 path=plover_get_program_directory(argv0);
57.64 - s=plover_strconcat(path,"/repodata/comps.xml",NULL);
57.65 + s=g_strconcat(path,"/repodata/comps.xml",NULL);
57.66 comps=plover_comps_new_from_file(s);
57.67 if (!comps)
57.68 {
57.69 perror(s);
57.70 exit(1);
57.71 }
57.72 - free(s);
57.73 + g_free(s);
57.74 prefix=plover_default_prefix_for_vendor(comps->vendor);
57.75 if (!plover_installed_files_match_prefix(prefix))
57.76 {
57.77 @@ -103,7 +61,12 @@
57.78 exit(1);
57.79 while(ch!='\n' && ch!=EOF)
57.80 ch=getchar();
57.81 - plover_remove(NULL);
57.82 + if (plover_remove(NULL,&error))
57.83 + {
57.84 + fprintf(stderr,"%s\n",error->message);
57.85 + g_error_free(error);
57.86 + exit(1);
57.87 + }
57.88 }
57.89 group=plover_comps_lookup_group(comps,"base");
57.90 if (!group)
57.91 @@ -111,21 +74,21 @@
57.92 fprintf(stderr,"No base group found in comps.xml\n");
57.93 exit(1);
57.94 }
57.95 - packages=vector_new();
57.96 + packages=plover_vector_new();
57.97 do
57.98 {
57.99 changed=0;
57.100 for(pkg=group->packages;pkg;pkg=pkg->next)
57.101 {
57.102 - if (vector_contains(packages,pkg->name))
57.103 + if (plover_vector_contains(packages,pkg->name))
57.104 continue;
57.105 if (pkg->type==COMPS_REQUIREMENT_DEFAULT ||
57.106 pkg->type==COMPS_REQUIREMENT_MANDATORY ||
57.107 pkg->type==COMPS_REQUIREMENT_CONDITIONAL &&
57.108 - vector_contains(packages,pkg->requires))
57.109 + plover_vector_contains(packages,pkg->requires))
57.110 {
57.111 changed++;
57.112 - vector_append(packages,pkg->name);
57.113 + plover_vector_append(packages,pkg->name);
57.114 }
57.115 }
57.116 } while(changed);
57.117 @@ -135,18 +98,31 @@
57.118 fprintf(stderr,"No packages to install\n");
57.119 exit(1);
57.120 }
57.121 - plover_install(path,prefix,packages->strings);
57.122 - vector_free(packages);
57.123 - free(prefix);
57.124 + if (!plover_install(path,prefix,packages->strings,&error))
57.125 + {
57.126 + fprintf(stderr,"%s\n",error->message);
57.127 + g_error_free(error);
57.128 + exit(1);
57.129 + }
57.130 + plover_vector_free(packages);
57.131 + g_free(prefix);
57.132 free(path);
57.133 }
57.134
57.135 int main(int argc,char **argv)
57.136 {
57.137 + GError *error=NULL;
57.138 razor_set_lua_loader("posix",luaopen_posix);
57.139 razor_set_lua_loader("whelk",luaopen_whelk);
57.140 if (argc>1 && !strcmp(argv[1],"-u"))
57.141 - plover_remove(NULL);
57.142 + {
57.143 + if (!plover_remove(NULL,&error))
57.144 + {
57.145 + fprintf(stderr,"%s\n",error->message);
57.146 + g_error_free(error);
57.147 + exit(1);
57.148 + }
57.149 + }
57.150 else
57.151 setup(argv[0]);
57.152 exit(0);
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/setup/setup.js.in Sat Nov 15 19:04:45 2014 +0000
58.3 @@ -0,0 +1,92 @@
58.4 +var WshShell = WScript.CreateObject("WScript.Shell");
58.5 +var ScriptPath = WScript.ScriptFullName.replace(/\\[^\\]*$/, "");
58.6 +var FileSystemObject = new ActiveXObject("Scripting.FileSystemObject");
58.7 +
58.8 +function RunSetup(args)
58.9 +{
58.10 + var OKButton = 0, ErrorIcon = 16, ForReading = 1;
58.11 + var path, command, i, ExecObject, text;
58.12 + path = FileSystemObject.BuildPath(ScriptPath, "setup.exe");
58.13 + command = "\"" + path + "\"";
58.14 + for(i = 0; i < args.Length; i++)
58.15 + command += " \"" + args.Item(i) + "\"";
58.16 + ExecObject = WshShell.Exec(command);
58.17 + if (!ExecObject.StdErr.AtEndOfStream)
58.18 + {
58.19 + text = "Setup failed for an unexpected reason. Please report "
58.20 + + "the following error to support@city-occupational.co.uk:\n\n"
58.21 + + ExecObject.StdErr.ReadAll();
58.22 + WshShell.Popup(text, 0, "Setup failed", OKButton + ErrorIcon);
58.23 + return false;
58.24 + }
58.25 + else if (ExecObject.ExitCode)
58.26 + {
58.27 + text = "Setup failed without giving a reason. Please report "
58.28 + + "this to support@city-occupational.co.uk";
58.29 + WshShell.Popup(text, 0, "Setup failed", OKButton + ErrorIcon);
58.30 + return false;
58.31 + }
58.32 + return true;
58.33 +}
58.34 +
58.35 +function Install()
58.36 +{
58.37 + var path;
58.38 + path = FileSystemObject.BuildPath(ScriptPath, "pre-inst.exe");
58.39 + WshShell.Run("\"" + path + "\"" + " --post \"wscript.exe"
58.40 + + " \\\"" + WScript.ScriptFullName + "\\\""
58.41 + + " --post %INSTALL_PREFIX% %TEST_RESULT%\"",
58.42 + 7, true);
58.43 +}
58.44 +
58.45 +function Uninstall()
58.46 +{
58.47 + var path;
58.48 + path = FileSystemObject.BuildPath(ScriptPath, "pre-inst.exe");
58.49 + WshShell.Run("\"" + path + "\"" + " -u --post \"wscript.exe"
58.50 + + " \\\"" + WScript.ScriptFullName + "\\\"" + " --postun\"", 7, true);
58.51 +}
58.52 +
58.53 +function PostInstall()
58.54 +{
58.55 + var OKButton = 0, InfoIcon = 64, text;
58.56 + var test_result, install_prefix, path, args;
58.57 + install_prefix = WScript.Arguments.Item(1);
58.58 + test_result = WScript.Arguments.Item(2);
58.59 + if (test_result == "pass")
58.60 + {
58.61 + path = FileSystemObject.BuildPath(install_prefix,
58.62 + "bin\\app-manager.exe");
58.63 + WshShell.Run("\"" + path + "\" --setup \"" + ScriptPath + "\"");
58.64 + }
58.65 + else
58.66 + {
58.67 + args = { Length:0, Item:function(){return nil} };
58.68 + if (RunSetup(args))
58.69 + {
58.70 + text = "Software installation completed successfully.";
58.71 + WshShell.Popup(text, 0, "Software Installation",
58.72 + OKButton + InfoIcon);
58.73 + }
58.74 + }
58.75 +}
58.76 +
58.77 +function PostUninstall()
58.78 +{
58.79 + var args = { Length:1, Item:function(){return "-u"} };
58.80 + var OKButton = 0, InfoIcon = 64, text;
58.81 + if (RunSetup(args))
58.82 + {
58.83 + text = "Uninstall completed successfully.";
58.84 + WshShell.Popup(text, 0, "Uninstall", OKButton + InfoIcon);
58.85 + }
58.86 +}
58.87 +
58.88 +if (WScript.Arguments.Length < 1)
58.89 + Install()
58.90 +else if (WScript.Arguments.Item(0) == "-u")
58.91 + Uninstall()
58.92 +else if (WScript.Arguments.Length >= 3 && WScript.Arguments.Item(0) == "--post")
58.93 + PostInstall()
58.94 +else if (WScript.Arguments.Item(0) == "--postun")
58.95 + PostUninstall()
59.1 --- a/update/Makefile.am Fri Mar 23 20:29:50 2012 +0000
59.2 +++ b/update/Makefile.am Sat Nov 15 19:04:45 2014 +0000
59.3 @@ -3,6 +3,7 @@
59.4 INCLUDES=-I$(top_srcdir)
59.5
59.6 bin_PROGRAMS=update
59.7 +bin_SCRIPTS=update.js
59.8
59.9 update_SOURCES=update.c
59.10 update_LDFLAGS=-all-static
59.11 @@ -10,13 +11,19 @@
59.12 update_SOURCES+=resources.rc update.exe.manifest
59.13 endif
59.14
59.15 -.png.pnm:
59.16 - pngtopnm $< | pnmquant 256 > $@
59.17 +.rc.$(OBJEXT):
59.18 + $(AM_V_GEN)$(WINDRES) resources.rc $@
59.19
59.20 resources.$(OBJEXT): resources.rc update.exe.manifest update.ico
59.21 - $(WINDRES) resources.rc $@
59.22 +
59.23 +%.js: $(srcdir)/%.js.in
59.24 + $(AM_V_GEN)sed -e 's/$$/\r/' $(srcdir)/$@.in > $@
59.25 +
59.26 +.png.pnm:
59.27 + $(AM_V_GEN)pngtopnm $< | pnmquant -quiet 256 > $@
59.28
59.29 update.ico: icon16.pnm icon22.pnm icon32.pnm
59.30 - ppmtowinicon -output=$@ $^
59.31 + $(AM_V_GEN)ppmtowinicon -output=$@ $^
59.32
59.33 -EXTRA_DIST=icon16.png icon22.png icon32.png
59.34 +EXTRA_DIST=icon16.png icon22.png icon32.png update.js.in
59.35 +CLEANFILES=update.js
60.1 --- a/update/resources.rc.in Fri Mar 23 20:29:50 2012 +0000
60.2 +++ b/update/resources.rc.in Sat Nov 15 19:04:45 2014 +0000
60.3 @@ -1,6 +1,8 @@
60.4 #include <winver.h>
60.5 #include <winuser.h>
60.6
60.7 +#pragma code_page(65001)
60.8 +
60.9 MAINICON ICON "update.ico"
60.10
60.11 VS_VERSION_INFO VERSIONINFO
60.12 @@ -20,7 +22,7 @@
60.13 VALUE "FileVersion","@PACKAGE_VERSION@"
60.14 VALUE "InternalName","update"
60.15 VALUE "LegalCopyright",
60.16 - "Copyright (c) 2009,2011,2012 J. Ali Harlow et al"
60.17 + "Copyright © 2009,2011,2012 J. Ali Harlow et al"
60.18 VALUE "OriginalFilename","update.exe"
60.19 VALUE "ProductName","plover"
60.20 VALUE "ProductVersion","@PACKAGE_VERSION@"
61.1 --- a/update/update.c Fri Mar 23 20:29:50 2012 +0000
61.2 +++ b/update/update.c Sat Nov 15 19:04:45 2014 +0000
61.3 @@ -27,18 +27,20 @@
61.4
61.5 void update(const char *argv0)
61.6 {
61.7 - char *path,*s,*prefix;
61.8 + char *path;
61.9 + gchar *s,*prefix;
61.10 int ch;
61.11 struct comps *comps;
61.12 + GError *error=NULL;
61.13 path=plover_get_program_directory(argv0);
61.14 - s=plover_strconcat(path,"/repodata/comps.xml",NULL);
61.15 + s=g_strconcat(path,"/repodata/comps.xml",NULL);
61.16 comps=plover_comps_new_from_file(s);
61.17 if (!comps)
61.18 {
61.19 perror(s);
61.20 exit(1);
61.21 }
61.22 - free(s);
61.23 + g_free(s);
61.24 prefix=plover_default_prefix_for_vendor(comps->vendor);
61.25 if (!plover_installed_files_match_prefix(prefix))
61.26 {
61.27 @@ -50,11 +52,21 @@
61.28 exit(1);
61.29 while(ch!='\n' && ch!=EOF)
61.30 ch=getchar();
61.31 - plover_remove(NULL);
61.32 + if (plover_remove(NULL,&error))
61.33 + {
61.34 + fprintf(stderr,"%s\n",error->message);
61.35 + g_error_free(error);
61.36 + exit(1);
61.37 + }
61.38 }
61.39 plover_comps_free(comps);
61.40 - plover_update(path,prefix,NULL);
61.41 - free(prefix);
61.42 + if (!plover_update(path,prefix,NULL,&error))
61.43 + {
61.44 + fprintf(stderr,"%s\n",error->message);
61.45 + g_error_free(error);
61.46 + exit(1);
61.47 + }
61.48 + g_free(prefix);
61.49 free(path);
61.50 }
61.51
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/update/update.js.in Sat Nov 15 19:04:45 2014 +0000
62.3 @@ -0,0 +1,68 @@
62.4 +var WshShell = WScript.CreateObject("WScript.Shell");
62.5 +var ScriptPath = WScript.ScriptFullName.replace(/\\[^\\]*$/, "");
62.6 +var FileSystemObject = new ActiveXObject("Scripting.FileSystemObject");
62.7 +
62.8 +function RunUpdate(args)
62.9 +{
62.10 + var OKButton = 0, ErrorIcon = 16, ForReading = 1;
62.11 + var path, command, i, ExecObject, text;
62.12 + path = FileSystemObject.BuildPath(ScriptPath, "update.exe");
62.13 + command = "\"" + path + "\"";
62.14 + for(i = 0; i < args.Length; i++)
62.15 + command += " \"" + args.Item(i) + "\"";
62.16 + ExecObject = WshShell.Exec(command);
62.17 + if (!ExecObject.StdErr.AtEndOfStream)
62.18 + {
62.19 + text = "Update failed for an unexpected reason. Please report "
62.20 + + "the following error to support@city-occupational.co.uk:\n\n"
62.21 + + ExecObject.StdErr.ReadAll();
62.22 + WshShell.Popup(text, 0, "Update failed", OKButton + ErrorIcon);
62.23 + return false;
62.24 + }
62.25 + else if (ExecObject.ExitCode)
62.26 + {
62.27 + text = "Update failed without giving a reason. Please report "
62.28 + + "this to support@city-occupational.co.uk";
62.29 + WshShell.Popup(text, 0, "Update failed", OKButton + ErrorIcon);
62.30 + return false;
62.31 + }
62.32 + return true;
62.33 +}
62.34 +
62.35 +function Update()
62.36 +{
62.37 + var path;
62.38 + path = FileSystemObject.BuildPath(ScriptPath, "pre-inst.exe");
62.39 + WshShell.Run("\"" + path + "\"" + " --post \"wscript.exe"
62.40 + + " \\\"" + WScript.ScriptFullName + "\\\""
62.41 + + " --post %INSTALL_PREFIX% %TEST_RESULT%\"",
62.42 + 7, true);
62.43 +}
62.44 +
62.45 +function PostUpdate()
62.46 +{
62.47 + var OKButton = 0, InfoIcon = 64, text;
62.48 + var test_result, install_prefix, path, args;
62.49 + install_prefix = WScript.Arguments.Item(1);
62.50 + test_result = WScript.Arguments.Item(2);
62.51 + if (test_result == "pass")
62.52 + {
62.53 + path = FileSystemObject.BuildPath(install_prefix,
62.54 + "bin\\app-manager.exe");
62.55 + WshShell.Run("\"" + path + "\" --update \"" + ScriptPath + "\"");
62.56 + }
62.57 + else
62.58 + {
62.59 + args = { Length:0, Item:function(){return nil} };
62.60 + if (RunUpdate(args))
62.61 + {
62.62 + text = "Software update completed successfully.";
62.63 + WshShell.Popup(text, 0, "Software Update", OKButton + InfoIcon);
62.64 + }
62.65 + }
62.66 +}
62.67 +
62.68 +if (WScript.Arguments.Length < 1)
62.69 + Update()
62.70 +else if (WScript.Arguments.Length >= 3 && WScript.Arguments.Item(0) == "--post")
62.71 + PostUpdate()