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

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

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

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

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

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

- uninstall (ideally as an installed program that hooks into Add/Remove programs
but even re-running the installer would be acceptable).
- xz support (smaller packages).
- repomd.xml and xml:base (would be needed for an Internet installer).
- graphical installer.
ali@25
     1
/*
ali@25
     2
 * Copyright (C) 2014  J. Ali Harlow <ali@juiblex.co.uk>
ali@25
     3
 *
ali@25
     4
 * This program is free software; you can redistribute it and/or modify
ali@25
     5
 * it under the terms of the GNU General Public License as published by
ali@25
     6
 * the Free Software Foundation; either version 2 of the License, or
ali@25
     7
 * (at your option) any later version.
ali@25
     8
 *
ali@25
     9
 * This program is distributed in the hope that it will be useful,
ali@25
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@25
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@25
    12
 * GNU General Public License for more details.
ali@25
    13
 *
ali@25
    14
 * You should have received a copy of the GNU General Public License along
ali@25
    15
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@25
    16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@25
    17
 */
ali@25
    18
ali@25
    19
#include "config.h"
ali@25
    20
#include <stdlib.h>
ali@25
    21
#include <string.h>
ali@25
    22
#ifdef WIN32
ali@25
    23
#include <windows.h>
ali@25
    24
#endif	/* WIN32 */
ali@25
    25
#include <lua.h>
ali@25
    26
#include <glib.h>
ali@25
    27
#include <gio/gio.h>
ali@25
    28
#include <gtk/gtk.h>
ali@25
    29
#include <whelk/whelk.h>
ali@25
    30
#include <plover/plover.h>
ali@25
    31
#include <plover/package.h>
ali@25
    32
#include <plover/packageset.h>
ali@25
    33
#include <plover-gtk/transactionhelper.h>
ali@25
    34
#include <plover-gtk/stockicons.h>
ali@25
    35
ali@25
    36
LUALIB_API int luaopen_posix(lua_State *L);
ali@25
    37
ali@25
    38
#define LOGO_NAME	"application-x-redhat-package-manager"
ali@25
    39
ali@25
    40
gboolean install(PloverPackageSet *installed,const char *path)
ali@25
    41
{
ali@25
    42
    gchar *s;
ali@30
    43
    const char *prefix,*unsatisfied;
ali@25
    44
    const char *filenames[2];
ali@25
    45
    GError *error=NULL;
ali@25
    46
    GSList *packages,*lnk;
ali@25
    47
    struct plover_vector *selected_packages;
ali@25
    48
    PloverPackage *package;
ali@25
    49
    PloverPackageSet *set;
ali@25
    50
    PloverRepository *upstream;
ali@25
    51
    PloverTransactionHelper *helper;
ali@25
    52
    helper=plover_transaction_helper_new(NULL);
ali@25
    53
    g_signal_connect(helper,"close",G_CALLBACK(gtk_main_quit),NULL);
ali@25
    54
    plover_transaction_helper_set_installed(helper,installed);
ali@25
    55
    if (plover_transaction_helper_get_error(helper,NULL))
ali@25
    56
    {
ali@25
    57
	plover_transaction_helper_present(helper);
ali@25
    58
	return TRUE;
ali@25
    59
    }
ali@25
    60
    filenames[0]=path;
ali@25
    61
    filenames[1]=NULL;
ali@25
    62
    upstream=plover_repository_new_from_files(filenames,&error);
ali@25
    63
    if (upstream)
ali@25
    64
	plover_transaction_helper_set_upstream(helper,upstream);
ali@25
    65
    else
ali@25
    66
    {
ali@25
    67
	plover_transaction_helper_set_error(helper,error,
ali@25
    68
	  "Software installation failed");
ali@25
    69
	g_clear_error(&error);
ali@25
    70
	plover_transaction_helper_present(helper);
ali@25
    71
	return TRUE;
ali@25
    72
    }
ali@25
    73
    prefix=plover_transaction_helper_get_prefix(helper,&error);
ali@25
    74
    if (error)
ali@25
    75
	g_clear_error(&error);
ali@25
    76
    else
ali@25
    77
    {
ali@25
    78
	s=g_strconcat(prefix?prefix:"","/var/log/open",NULL);
ali@25
    79
	plover_log_open(s);
ali@25
    80
	g_free(s);
ali@25
    81
    }
ali@25
    82
    set=plover_repository_get_package_set(upstream);
ali@25
    83
    packages=plover_package_set_get_packages(set);
ali@25
    84
    selected_packages=plover_vector_new();
ali@25
    85
    for(lnk=packages;lnk;lnk=lnk->next)
ali@25
    86
    {
ali@25
    87
	package=PLOVER_PACKAGE(lnk->data);
ali@25
    88
	plover_vector_append(selected_packages,
ali@25
    89
	  plover_package_get_name(package));
ali@25
    90
    }
ali@25
    91
    if (!plover_transaction_helper_install_packages(helper,selected_packages,
ali@25
    92
      &error))
ali@25
    93
    {
ali@25
    94
	if (g_error_matches(error,PLOVER_GENERAL_ERROR,
ali@25
    95
	  PLOVER_GENERAL_ERROR_NO_WORK))
ali@25
    96
	{
ali@25
    97
	    g_error_free(error);
ali@25
    98
	    error=g_error_new_literal(PLOVER_GENERAL_ERROR,
ali@25
    99
	      PLOVER_GENERAL_ERROR_NO_WORK,
ali@25
   100
	      "All packages already installed");
ali@25
   101
	    plover_transaction_helper_set_error(helper,error,
ali@25
   102
	      "Software installation");
ali@25
   103
	}
ali@25
   104
	else if (g_error_matches(error,PLOVER_GENERAL_ERROR,
ali@25
   105
	  PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET))
ali@25
   106
	{
ali@25
   107
	    g_error_free(error);
ali@25
   108
	    unsatisfied=plover_transaction_helper_get_unsatisfied(helper);
ali@25
   109
	    error=g_error_new(PLOVER_GENERAL_ERROR,
ali@25
   110
	      PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET,
ali@25
   111
	      "Software cannot be installed because the following requirements "
ali@25
   112
	      "were not met:\n\n%s",unsatisfied);
ali@25
   113
	    plover_transaction_helper_set_error(helper,error,
ali@25
   114
	      "Software installation failed");
ali@25
   115
	}
ali@25
   116
	else
ali@25
   117
	    plover_transaction_helper_set_error(helper,error,
ali@25
   118
	      "Software installation failed");
ali@25
   119
	g_error_free(error);
ali@25
   120
    }
ali@25
   121
    plover_vector_free(selected_packages);
ali@25
   122
    g_object_unref(upstream);
ali@25
   123
    plover_transaction_helper_present(helper);
ali@25
   124
    return TRUE;
ali@25
   125
}
ali@25
   126
ali@25
   127
static void install_icons(void)
ali@25
   128
{
ali@25
   129
    GtkIconSet *icon_set;
ali@25
   130
    plover_icons_add_to_stock("mimetypes",LOGO_NAME);
ali@25
   131
    icon_set=gtk_icon_factory_lookup_default(LOGO_NAME);
ali@25
   132
    gtk_window_set_default_icon_name(LOGO_NAME);
ali@25
   133
}
ali@25
   134
ali@25
   135
int main(int argc,char **argv)
ali@25
   136
{
ali@25
   137
    GError *err=0;
ali@25
   138
    gchar *install_path=NULL;
ali@25
   139
    PloverPackageSet *set;
ali@25
   140
#if 0
ali@30
   141
    gsize len;
ali@30
   142
    gchar *s,*t,*contents;
ali@25
   143
    GSList *objects,*lnk;
ali@25
   144
#endif
ali@25
   145
    GOptionEntry options[]={
ali@25
   146
	{"install",0,0,G_OPTION_ARG_FILENAME,&install_path,
ali@25
   147
	  "Install an RPM","path"},
ali@25
   148
	{NULL}
ali@25
   149
    };
ali@25
   150
#ifdef WIN32
ali@25
   151
    /*
ali@25
   152
     * plover-open is normally a GUI application, but rpm scripts may well
ali@25
   153
     * call console applications and it looks ugly if console windows keep
ali@25
   154
     * popping up. Avoid this by allocating our own console and hiding it.
ali@25
   155
     * Note:
ali@25
   156
     *	- If plover-open is a console application (typically for debugging),
ali@25
   157
     *    then skip this step.
ali@25
   158
     *  - Call ShowWindow twice to negate special handling on first call.
ali@25
   159
     */
ali@25
   160
    if (!GetConsoleWindow())
ali@25
   161
    {
ali@25
   162
	AllocConsole();
ali@25
   163
	ShowWindow(GetConsoleWindow(),SW_HIDE);
ali@25
   164
	ShowWindow(GetConsoleWindow(),SW_HIDE);
ali@25
   165
    }
ali@25
   166
#endif
ali@31
   167
    plover_exception_handler_init();
ali@38
   168
    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
ali@38
   169
    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
ali@25
   170
    if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
ali@25
   171
    {
ali@25
   172
	g_printerr("%s\n",err->message);
ali@25
   173
	exit(1);
ali@25
   174
    }
ali@25
   175
    install_icons();
ali@25
   176
#if 0
ali@25
   177
    ui=gtk_builder_new();
ali@25
   178
    if (!g_file_get_contents("plover-open.ui",&contents,&len,&err) &&
ali@25
   179
      g_error_matches(err,G_FILE_ERROR,G_FILE_ERROR_NOENT))
ali@25
   180
    {
ali@25
   181
#ifdef WIN32
ali@25
   182
	t=g_win32_get_package_installation_directory_of_module(NULL);
ali@25
   183
	s=g_build_filename(t,"share","plover","plover-open.ui",NULL);
ali@25
   184
	g_free(t);
ali@25
   185
#else
ali@25
   186
	s=g_build_filename(PLOVER_DATADIR,"plover-open.ui",NULL);
ali@25
   187
#endif
ali@25
   188
	g_clear_error(&err);
ali@25
   189
	(void)g_file_get_contents(s,&contents,&len,&err);
ali@25
   190
	g_free(s);
ali@25
   191
    }
ali@25
   192
    if (!err)
ali@25
   193
    {
ali@25
   194
	(void)gtk_builder_add_from_string(ui,contents,len,&err);
ali@25
   195
	g_free(contents);
ali@25
   196
    }
ali@25
   197
    if (err)
ali@25
   198
    {
ali@25
   199
	g_error("%s",err->message);
ali@25
   200
	exit(0);
ali@25
   201
    }
ali@25
   202
    gtk_builder_connect_signals(ui,NULL);
ali@25
   203
#endif
ali@25
   204
    set=plover_package_set_new();
ali@25
   205
    (void)plover_package_set_open(set,"",TRUE,NULL);
ali@25
   206
    if (install_path)
ali@25
   207
	if (install(set,install_path))
ali@25
   208
	    gtk_main();
ali@25
   209
    g_clear_object(&set);
ali@25
   210
#if 0
ali@25
   211
    objects=gtk_builder_get_objects(ui);
ali@25
   212
    for(lnk=objects;lnk;lnk=lnk->next)
ali@25
   213
	if (GTK_IS_WIDGET(lnk->data) &&
ali@25
   214
	  gtk_widget_is_toplevel(GTK_WIDGET(lnk->data)))
ali@25
   215
	    gtk_widget_destroy(GTK_WIDGET(lnk->data));
ali@25
   216
    g_slist_free(objects);
ali@25
   217
    g_clear_object(&ui);
ali@25
   218
#endif
ali@25
   219
    g_free(install_path);
ali@25
   220
    exit(0);
ali@25
   221
}