pre-inst/pre-inst.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Jul 07 19:03:54 2016 +0100 (2016-07-07)
changeset 58 4b52e95a0104
parent 38 a29623b68ca2
child 80 671df13f1304
permissions -rw-r--r--
First steps towards adding updatez
ali@24
     1
/*
ali@24
     2
 * Copyright (C) 2014  J. Ali Harlow <ali@juiblex.co.uk>
ali@24
     3
 *
ali@24
     4
 * This program is free software; you can redistribute it and/or modify
ali@24
     5
 * it under the terms of the GNU General Public License as published by
ali@24
     6
 * the Free Software Foundation; either version 2 of the License, or
ali@24
     7
 * (at your option) any later version.
ali@24
     8
 *
ali@24
     9
 * This program is distributed in the hope that it will be useful,
ali@24
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@24
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@24
    12
 * GNU General Public License for more details.
ali@24
    13
 *
ali@24
    14
 * You should have received a copy of the GNU General Public License along
ali@24
    15
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@24
    16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@24
    17
 *
ali@24
    18
 * References:
ali@24
    19
 *	http://www.transmissionzero.co.uk/computing/win32-apps-with-mingw/
ali@24
    20
 */
ali@24
    21
ali@24
    22
#include "config.h"
ali@24
    23
#ifndef WIN32
ali@24
    24
#define _XOPEN_SOURCE 500
ali@24
    25
#endif
ali@24
    26
#include <stdlib.h>
ali@24
    27
#include <stdio.h>
ali@24
    28
#include <string.h>
ali@24
    29
#include <lua.h>
ali@24
    30
#include <razor.h>
ali@24
    31
#include <plover/plover.h>
ali@24
    32
#include <whelk/whelk.h>
ali@24
    33
#ifdef WIN32
ali@24
    34
#include <windows.h>
ali@24
    35
#include <process.h>
ali@24
    36
#include <commctrl.h>
ali@24
    37
#include "resource.h"
ali@24
    38
ali@24
    39
#ifndef FOF_NO_UI
ali@24
    40
#define FOF_NO_UI	(FOF_SILENT|FOF_NOCONFIRMATION|FOF_NOERRORUI|\
ali@24
    41
			FOF_NOCONFIRMMKDIR)
ali@24
    42
#endif
ali@24
    43
ali@24
    44
#else	/* WIN32 */
ali@24
    45
#include <ftw.h>
ali@24
    46
#endif	/* WIN32 */
ali@24
    47
ali@24
    48
#ifdef WIN32
ali@24
    49
/* Under WIN32, g_spawn requires a helper program which we'd rather avoid */
ali@24
    50
#undef USE_G_SPAWN
ali@24
    51
#else
ali@24
    52
#define USE_G_SPAWN
ali@24
    53
#endif
ali@24
    54
ali@24
    55
LUALIB_API int luaopen_posix(lua_State *L);
ali@24
    56
ali@24
    57
#ifdef WIN32
ali@24
    58
DWORD main_thread_id;
ali@24
    59
#endif
ali@24
    60
ali@24
    61
gchar *prefix;
ali@24
    62
ali@24
    63
int verify_and_fix(const char *root)
ali@24
    64
{
ali@24
    65
    return 0;
ali@24
    66
}
ali@24
    67
ali@24
    68
#ifdef WIN32
ali@24
    69
INT_PTR CALLBACK ProgressDialogProc(HWND dialog,UINT msg,WPARAM w_param,
ali@24
    70
  LPARAM l_param)
ali@24
    71
{
ali@24
    72
    HWND progress;
ali@24
    73
    DWORD style;
ali@24
    74
    switch (msg)
ali@24
    75
    {
ali@24
    76
	case WM_INITDIALOG:
ali@24
    77
	    progress=GetDlgItem(dialog,IDC_PROGRESS); 
ali@24
    78
	    style=GetWindowLong(progress,GWL_STYLE);
ali@24
    79
	    SetWindowLong(progress,GWL_STYLE,style|PBS_MARQUEE);
ali@24
    80
	    SendMessage(progress,PBM_SETMARQUEE,(WPARAM)TRUE,(LPARAM)30);
ali@24
    81
	    return (INT_PTR)TRUE;
ali@24
    82
    }
ali@24
    83
    return (INT_PTR)FALSE;
ali@24
    84
}
ali@24
    85
#endif
ali@24
    86
ali@24
    87
#ifdef WIN32
ali@24
    88
__stdcall
ali@24
    89
#endif
ali@24
    90
unsigned pre_install_thread(void *data)
ali@24
    91
{
ali@24
    92
    int retval;
ali@24
    93
    char *path=data;
ali@46
    94
    gchar *s,*uri;
ali@24
    95
    char *install[]={"plover-gtkui",NULL};
ali@24
    96
    GError *error=NULL;
ali@24
    97
    prefix=plover_pre_install_prefix();
ali@24
    98
    s=g_strconcat(prefix,"/var/log/pre-install",NULL);
ali@24
    99
    plover_log_open(s);
ali@24
   100
    g_free(s);
ali@24
   101
    s=g_strconcat(prefix,"/var/lib/razor",NULL);
ali@46
   102
    uri=razor_path_to_uri(s);
ali@24
   103
    g_free(s);
ali@46
   104
    razor_set_database_uri(uri);
ali@46
   105
    free(uri);
ali@24
   106
    if (verify_and_fix(prefix))
ali@24
   107
    {
ali@24
   108
	free(path);
ali@24
   109
	g_free(prefix);
ali@24
   110
	return -1;
ali@24
   111
    }
ali@24
   112
    retval=!plover_install(path,prefix,install,&error);
ali@24
   113
    if (!retval)
ali@24
   114
	retval=!plover_update(path,prefix,NULL,&error);
ali@24
   115
    if (error)
ali@24
   116
    {
ali@24
   117
	fprintf(stderr,"%s\n",error->message);
ali@24
   118
	g_error_free(error);
ali@24
   119
    }
ali@24
   120
    free(path);
ali@24
   121
#ifdef WIN32
ali@24
   122
    PostQuitMessage(retval);
ali@24
   123
    PostThreadMessage(main_thread_id,WM_QUIT,retval,0);
ali@24
   124
    _endthreadex(retval);
ali@24
   125
#endif
ali@24
   126
    return retval;
ali@24
   127
}
ali@24
   128
ali@24
   129
/*
ali@24
   130
 * The idea is that if pre_install() fails, update/setup should fall back
ali@24
   131
 * to console interfaces.
ali@24
   132
 */
ali@24
   133
#ifdef WIN32
ali@24
   134
HANDLE
ali@24
   135
#else
ali@24
   136
void *
ali@24
   137
#endif
ali@24
   138
pre_install(const char *argv0)
ali@24
   139
{
ali@24
   140
#ifdef WIN32
ali@24
   141
    HANDLE retval;
ali@24
   142
#else
ali@24
   143
    void *retval;
ali@24
   144
#endif
ali@24
   145
    char *path;
ali@38
   146
    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
ali@38
   147
    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
ali@24
   148
    path=plover_get_program_directory(argv0);
ali@24
   149
#ifdef WIN32
ali@24
   150
    retval=(HANDLE)_beginthreadex(NULL,0,pre_install_thread,path,0,NULL);
ali@24
   151
#else
ali@24
   152
    if (pre_install_thread(path))
ali@24
   153
	retval=NULL;
ali@24
   154
    else
ali@24
   155
	retval=(void *)1;		/* Non-NULL to indicate success */
ali@24
   156
#endif
ali@24
   157
    return retval;
ali@24
   158
}
ali@24
   159
ali@24
   160
#ifndef WIN32
ali@24
   161
int remove_ignore(const char *fpath,const struct stat *sb,int typeflag,
ali@24
   162
  struct FTW *ftwbuf)
ali@24
   163
{
ali@24
   164
    (void)remove(fpath);
ali@24
   165
    return 0;
ali@24
   166
}
ali@24
   167
#endif
ali@24
   168
ali@24
   169
gboolean deltree(const char *path)
ali@24
   170
{
ali@24
   171
#ifdef WIN32
ali@24
   172
    /* Based on g_local_file_trash() */
ali@24
   173
    SHFILEOPSTRUCTW op={0};
ali@24
   174
    gboolean success;
ali@24
   175
    wchar_t *wfilename;
ali@24
   176
    long len;
ali@24
   177
    wfilename=g_utf8_to_utf16(path,-1,NULL,&len,NULL);
ali@24
   178
    /* SHFILEOPSTRUCT.pFrom is double-zero-terminated */
ali@24
   179
    wfilename=g_renew(wchar_t,wfilename,len+2);
ali@24
   180
    wfilename[len+1]=0;
ali@24
   181
    op.wFunc=FO_DELETE;
ali@24
   182
    op.pFrom=wfilename;
ali@24
   183
    op.fFlags=FOF_NO_UI;
ali@24
   184
    success=!SHFileOperationW(&op);
ali@24
   185
    if (success && op.fAnyOperationsAborted)
ali@24
   186
	success=FALSE;
ali@24
   187
    g_free(wfilename);
ali@24
   188
    return success;
ali@24
   189
#else
ali@24
   190
    return nftw(path,remove_ignore,64,FTW_DEPTH|FTW_PHYS);
ali@24
   191
#endif
ali@24
   192
}
ali@24
   193
ali@24
   194
gboolean pre_uninstall(void)
ali@24
   195
{
ali@24
   196
    gboolean success;
ali@46
   197
    gchar *s,*uri;
ali@24
   198
    GError *error=NULL;
ali@38
   199
    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
ali@38
   200
    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
ali@24
   201
    prefix=plover_pre_install_prefix();
ali@24
   202
    s=g_strconcat(prefix,"/var/lib/razor",NULL);
ali@46
   203
    uri=razor_path_to_uri(s);
ali@24
   204
    g_free(s);
ali@46
   205
    razor_set_database_uri(uri);
ali@46
   206
    free(uri);
ali@24
   207
    success=plover_remove(NULL,&error);
ali@24
   208
    if (error)
ali@24
   209
    {
ali@24
   210
	fprintf(stderr,"%s\n",error->message);
ali@24
   211
	g_error_free(error);
ali@24
   212
    }
ali@24
   213
    deltree(prefix);
ali@24
   214
    return success;
ali@24
   215
}
ali@24
   216
ali@24
   217
#if defined(WIN32) && !defined(USE_G_SPAWN)
ali@24
   218
/* Based on glib's g_spawn_win32.c */
ali@24
   219
ali@24
   220
static gchar *
ali@24
   221
win32_cmdline_quote(const char *string)
ali@24
   222
{
ali@24
   223
    const gchar *p=string;
ali@24
   224
    gchar *retval,*q;
ali@24
   225
    gint len=0;
ali@24
   226
    gboolean need_dblquotes=FALSE;
ali@24
   227
    while (*p)
ali@24
   228
    {
ali@24
   229
	if (*p==' ' || *p=='\t')
ali@24
   230
	    need_dblquotes=TRUE;
ali@24
   231
	else if (*p=='"')
ali@24
   232
	    len++;
ali@24
   233
	else if (*p=='\\')
ali@24
   234
	{
ali@24
   235
	    const gchar *pp=p;
ali@24
   236
	    while (*pp && *pp=='\\')
ali@24
   237
		pp++;
ali@24
   238
	    if (*pp=='"')
ali@24
   239
		len++;
ali@24
   240
	}
ali@24
   241
	len++;
ali@24
   242
	p++;
ali@24
   243
    }
ali@24
   244
    q=retval=g_malloc(len+need_dblquotes*2+1);
ali@24
   245
    p=string;
ali@24
   246
    if (need_dblquotes)
ali@24
   247
	*q++='"';
ali@24
   248
    while (*p)
ali@24
   249
    {
ali@24
   250
	if (*p=='"')
ali@24
   251
	    *q++='\\';
ali@24
   252
	else if (*p=='\\')
ali@24
   253
	{
ali@24
   254
	    const gchar *pp=p;
ali@24
   255
	    while (*pp && *pp=='\\')
ali@24
   256
		pp++;
ali@24
   257
	    if (*pp=='"')
ali@24
   258
		*q++='\\';
ali@24
   259
	}
ali@24
   260
	*q++=*p;
ali@24
   261
	p++;
ali@24
   262
    }
ali@24
   263
    if (need_dblquotes)
ali@24
   264
	*q++='"';
ali@24
   265
    *q++='\0';
ali@24
   266
    return retval;
ali@24
   267
}
ali@24
   268
ali@24
   269
/* Create a win32-style wide-character argv with suitable quoting */
ali@24
   270
wchar_t **win32_argv_import(char **argv,GError **error)
ali@24
   271
{
ali@24
   272
    int i,n;
ali@24
   273
    gchar *s;
ali@24
   274
    wchar_t **wargv;
ali@24
   275
    GError *tmp_error=NULL;
ali@24
   276
    n=g_strv_length(argv);
ali@24
   277
    wargv=g_new(wchar_t *,n+1);
ali@24
   278
    for(i=0;i<n;i++)
ali@24
   279
    {
ali@24
   280
	s=win32_cmdline_quote(argv[i]);
ali@24
   281
	wargv[i]=g_utf8_to_utf16(s,-1,NULL,NULL,&tmp_error);
ali@24
   282
	g_free(s);
ali@24
   283
	if (!wargv[i])
ali@24
   284
	{
ali@24
   285
	    g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
ali@24
   286
	      "Invalid argument #%d: %s",i,tmp_error->message);
ali@24
   287
	    g_error_free(tmp_error);
ali@24
   288
	    for(i--;i>=0;i--)
ali@24
   289
		g_free(wargv[i]);
ali@24
   290
	    g_free(wargv);
ali@24
   291
	    return FALSE;
ali@24
   292
	}
ali@24
   293
    }
ali@24
   294
    wargv[i]=NULL;
ali@24
   295
    return wargv;
ali@24
   296
}
ali@24
   297
ali@24
   298
gboolean spawn_sync(char **argv,GError **error)
ali@24
   299
{
ali@24
   300
    wchar_t *wargv0,**wargv;
ali@24
   301
    gintptr rc;
ali@24
   302
    GError *tmp_error=NULL;
ali@24
   303
    wargv0=g_utf8_to_utf16(argv[0],-1,NULL,NULL,&tmp_error);
ali@24
   304
    if (!wargv0)
ali@24
   305
    {
ali@24
   306
	fprintf(stderr,"Conversion error in post\n");
ali@24
   307
	g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
ali@24
   308
	  "Invalid program name: %s",tmp_error->message);
ali@24
   309
	g_error_free(tmp_error);
ali@24
   310
	return FALSE;
ali@24
   311
    }
ali@24
   312
    wargv=win32_argv_import(argv,error);
ali@24
   313
    if (!wargv)
ali@24
   314
    {
ali@24
   315
	fprintf(stderr,"Conversion error in post\n");
ali@24
   316
	g_free(wargv0);
ali@24
   317
	return FALSE;
ali@24
   318
    }
ali@24
   319
    errno=0;
ali@24
   320
    rc=_wspawnvp(P_WAIT,wargv0,(const wchar_t **)wargv);
ali@24
   321
    g_free(wargv0);
ali@24
   322
    g_strfreev((gchar **)wargv);
ali@24
   323
    if (rc==-1 && errno!=0)
ali@24
   324
    {
ali@24
   325
	fprintf(stderr,"Failed to start post command (%s)\n",g_strerror(errno));
ali@24
   326
	g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
ali@24
   327
	  "Failed to execute post command: %s",g_strerror(errno));
ali@24
   328
	return FALSE;
ali@24
   329
    }
ali@24
   330
    if (rc!=EXIT_SUCCESS)
ali@24
   331
    {
ali@24
   332
	fprintf(stderr,"post command failed (%ld)\n",(long)rc);
ali@24
   333
	g_set_error(error,G_SPAWN_ERROR,G_SPAWN_ERROR_FAILED,
ali@24
   334
	  "Post command exited with code %ld",(long)rc);
ali@24
   335
	return FALSE;
ali@24
   336
    }
ali@24
   337
    return TRUE;
ali@24
   338
}
ali@24
   339
ali@24
   340
#endif /* defined(WIN32) && !defined(USE_G_SPAWN) */
ali@24
   341
ali@24
   342
/*
ali@24
   343
 * Run a command after completing request.
ali@24
   344
 *
ali@24
   345
 * Command may refer to %INSTALL_PREFIX% which will be replaced by the
ali@24
   346
 * (first) install prefix used and/or %TEST_RESULT% which will be replaced
ali@24
   347
 * bu either "pass" or "fail" depending as to whether the request succeeded
ali@24
   348
 * or not. Command may also include double quotes which will be used to
ali@24
   349
 * affect how the command is split into arguments much like a shell does.
ali@24
   350
 */
ali@24
   351
gboolean run_post(int argc,char **argv,gboolean test_result,GError **error)
ali@24
   352
{
ali@24
   353
    int i,post_argc;
ali@24
   354
    char *s;
ali@24
   355
    gchar *expanded;
ali@24
   356
    gchar **post_argv;
ali@24
   357
#ifdef USE_G_SPAWN
ali@24
   358
    gchar *standard_output,*standard_error;
ali@24
   359
    int exit_status;
ali@24
   360
#endif
ali@24
   361
    GError *tmp_error=NULL;
ali@24
   362
    if (argc<1)
ali@24
   363
    {
ali@24
   364
	g_set_error_literal(error,G_FILE_ERROR,G_FILE_ERROR_NOENT,
ali@24
   365
	  "--post: No command given");
ali@24
   366
	return FALSE;
ali@24
   367
    }
ali@24
   368
    printf("Running post command: %s\n",argv[1]);
ali@24
   369
    if (!g_shell_parse_argv(argv[1],&post_argc,&post_argv,&tmp_error))
ali@24
   370
    {
ali@24
   371
	g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[1]);
ali@24
   372
	return FALSE;
ali@24
   373
    }
ali@24
   374
    for(i=0;i<post_argc;i++)
ali@24
   375
    {
ali@24
   376
	s=strstr(post_argv[i],"%INSTALL_PREFIX%");
ali@24
   377
	if (s)
ali@24
   378
	{
ali@24
   379
	    *s='\0';
ali@24
   380
	    s+=strlen("%INSTALL_PREFIX%");
ali@24
   381
	    expanded=g_strconcat(post_argv[i],prefix,s,NULL);
ali@24
   382
	    g_free(post_argv[i]);
ali@24
   383
	    post_argv[i]=expanded;
ali@24
   384
	}
ali@24
   385
	s=strstr(post_argv[i],"%TEST_RESULT%");
ali@24
   386
	if (s)
ali@24
   387
	{
ali@24
   388
	    *s='\0';
ali@24
   389
	    s+=strlen("%TEST_RESULT%");
ali@24
   390
	    expanded=g_strconcat(post_argv[i],test_result?"pass":"fail",s,NULL);
ali@24
   391
	    g_free(post_argv[i]);
ali@24
   392
	    post_argv[i]=expanded;
ali@24
   393
	}
ali@24
   394
    }
ali@24
   395
#ifdef USE_G_SPAWN
ali@24
   396
    if (!g_spawn_sync(NULL,post_argv,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL,
ali@24
   397
      &standard_output,&standard_error,&exit_status,&tmp_error))
ali@24
   398
    {
ali@24
   399
	fprintf(stderr,"Failed to start post command\n");
ali@24
   400
	g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
ali@24
   401
	return FALSE;
ali@24
   402
    }
ali@24
   403
    if (standard_output && *standard_output)
ali@24
   404
    {
ali@24
   405
	printf("Output from post command %s:\n",post_argv[0]);
ali@24
   406
	fputs(standard_output,stdout);
ali@24
   407
    }
ali@24
   408
    g_free(standard_output);
ali@24
   409
    if (standard_error && *standard_error)
ali@24
   410
    {
ali@24
   411
	printf("Error output from post command %s:\n",post_argv[0]);
ali@24
   412
	fputs(standard_error,stdout);
ali@24
   413
    }
ali@24
   414
    g_free(standard_error);
ali@24
   415
    if (!g_spawn_check_exit_status(exit_status,&tmp_error))
ali@24
   416
    {
ali@24
   417
	fprintf(stderr,"post command failed\n");
ali@24
   418
	g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
ali@24
   419
	return FALSE;
ali@24
   420
    }
ali@24
   421
#else
ali@24
   422
    if (!spawn_sync(post_argv,&tmp_error))
ali@24
   423
    {
ali@24
   424
	g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
ali@24
   425
	return FALSE;
ali@24
   426
    }
ali@24
   427
#endif
ali@24
   428
    return TRUE;
ali@24
   429
}
ali@24
   430
ali@24
   431
#ifdef WIN32
ali@24
   432
DWORD win32_pre_install_gui(char *argv0)
ali@24
   433
{
ali@24
   434
    HANDLE thread;
ali@24
   435
    INITCOMMONCONTROLSEX icc={0,};
ali@24
   436
    MSG msg;
ali@24
   437
    DWORD retval;
ali@24
   438
    main_thread_id=GetCurrentThreadId();
ali@24
   439
    thread=(HANDLE)pre_install(argv0);
ali@24
   440
    if (!thread)
ali@24
   441
	return EXIT_FAILURE;
ali@24
   442
    icc.dwSize=sizeof(icc);
ali@24
   443
    icc.dwICC=ICC_WIN95_CLASSES;
ali@24
   444
    InitCommonControlsEx(&icc);
ali@24
   445
    DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PROGRESSDIALOG),NULL,
ali@24
   446
      &ProgressDialogProc);
ali@24
   447
    while(GetMessage(&msg,NULL,0,0)>0)
ali@24
   448
    {
ali@24
   449
	TranslateMessage(&msg);
ali@24
   450
	DispatchMessage(&msg);
ali@24
   451
    }
ali@24
   452
    WaitForSingleObject(thread,INFINITE);
ali@24
   453
    GetExitCodeThread(thread,&retval);
ali@24
   454
    CloseHandle(thread);
ali@24
   455
    return retval;
ali@24
   456
}
ali@24
   457
#endif	/* WIN32 */
ali@24
   458
ali@24
   459
int main(int argc,char **argv)
ali@24
   460
{
ali@24
   461
    gboolean success;
ali@24
   462
    GError *error=NULL;
ali@24
   463
#ifdef WIN32
ali@24
   464
    /*
ali@24
   465
     * pre-inst is normally a GUI application, but rpm scripts may well
ali@24
   466
     * call console applications and it looks ugly if console windows keep
ali@24
   467
     * popping up. Avoid this by allocating our own console and hiding it.
ali@24
   468
     * Note:
ali@24
   469
     *	- If pre-inst is a console application (typically for debugging),
ali@24
   470
     *    then skip this step.
ali@24
   471
     *  - Call ShowWindow twice to negate special handling on first call.
ali@24
   472
     */
ali@24
   473
    if (!GetConsoleWindow())
ali@24
   474
    {
ali@24
   475
	AllocConsole();
ali@24
   476
	ShowWindow(GetConsoleWindow(),SW_HIDE);
ali@24
   477
	ShowWindow(GetConsoleWindow(),SW_HIDE);
ali@24
   478
    }
ali@24
   479
#endif
ali@31
   480
    plover_exception_handler_init();
ali@24
   481
    if (argc>1 && !strcmp(argv[1],"-u"))
ali@24
   482
    {
ali@24
   483
	success=pre_uninstall();
ali@24
   484
	argc--;
ali@24
   485
	argv++;
ali@24
   486
    }
ali@24
   487
    else
ali@24
   488
#ifdef WIN32
ali@24
   489
	success=win32_pre_install_gui(argv[0])==EXIT_SUCCESS;
ali@24
   490
#else
ali@24
   491
	success=!!pre_install(argv[0]);
ali@24
   492
#endif
ali@24
   493
    if (argc>1 && !strcmp(argv[1],"--post") &&
ali@24
   494
      !run_post(argc-1,argv+1,success,&error))
ali@24
   495
    {
ali@24
   496
#ifndef WIN32
ali@24
   497
	fprintf(stderr,"Error in post: %s\n",error->message);
ali@24
   498
#else
ali@24
   499
	MessageBox(NULL,error->message,"Error in post",MB_ICONERROR|MB_OK);
ali@24
   500
#endif
ali@24
   501
	g_error_free(error);
ali@24
   502
	success=FALSE;
ali@24
   503
    }
ali@24
   504
#ifdef WIN32
ali@24
   505
    return success?EXIT_SUCCESS:EXIT_FAILURE;
ali@24
   506
#else
ali@24
   507
    return success?0:1;
ali@24
   508
#endif
ali@24
   509
}