diff -r 212150407fcc -r d2d88f14283e pre-inst/pre-inst.c --- a/pre-inst/pre-inst.c Tue Jul 14 13:17:21 2020 +0100 +++ b/pre-inst/pre-inst.c Wed Jul 15 11:54:06 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 J. Ali Harlow + * Copyright (C) 2014, 2020 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ #else /* WIN32 */ #include #endif /* WIN32 */ +#include "post.h" #ifdef WIN32 /* Under WIN32, g_spawn requires a helper program which we'd rather avoid */ @@ -337,6 +338,47 @@ #endif /* defined(WIN32) && !defined(USE_G_SPAWN) */ +gboolean pre_install_spawn_sync(char **argv,GError **error) +{ + GError *tmp_error=NULL; +#ifdef USE_G_SPAWN + gchar *standard_output,*standard_error; + int exit_status; + if (!g_spawn_sync(NULL,argv,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL, + &standard_output,&standard_error,&exit_status,&tmp_error)) + { + fprintf(stderr,"Failed to start post command\n"); + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[0]); + return FALSE; + } + if (standard_output && *standard_output) + { + printf("Output from post command %s:\n",argv[0]); + fputs(standard_output,stdout); + } + g_free(standard_output); + if (standard_error && *standard_error) + { + printf("Error output from post command %s:\n",argv[0]); + fputs(standard_error,stdout); + } + g_free(standard_error); + if (!g_spawn_check_exit_status(exit_status,&tmp_error)) + { + fprintf(stderr,"post command failed\n"); + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[0]); + return FALSE; + } +#else + if (!spawn_sync(argv,&tmp_error)) + { + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[0]); + return FALSE; + } +#endif + return TRUE; +} + /* * Run a command after completing request. * @@ -354,10 +396,6 @@ char *s; gchar *expanded; gchar **post_argv; -#ifdef USE_G_SPAWN - gchar *standard_output,*standard_error; - int exit_status; -#endif GError *tmp_error=NULL; if (argc<2) { @@ -401,40 +439,7 @@ post_argv[i]=expanded; } } -#ifdef USE_G_SPAWN - if (!g_spawn_sync(NULL,post_argv,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL, - &standard_output,&standard_error,&exit_status,&tmp_error)) - { - fprintf(stderr,"Failed to start post command\n"); - g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]); - return FALSE; - } - if (standard_output && *standard_output) - { - printf("Output from post command %s:\n",post_argv[0]); - fputs(standard_output,stdout); - } - g_free(standard_output); - if (standard_error && *standard_error) - { - printf("Error output from post command %s:\n",post_argv[0]); - fputs(standard_error,stdout); - } - g_free(standard_error); - if (!g_spawn_check_exit_status(exit_status,&tmp_error)) - { - fprintf(stderr,"post command failed\n"); - g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]); - return FALSE; - } -#else - if (!spawn_sync(post_argv,&tmp_error)) - { - g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]); - return FALSE; - } -#endif - return TRUE; + return pre_install_spawn_sync(post_argv,error); } #ifdef WIN32 @@ -498,6 +503,71 @@ return uri; } +gboolean pre_install_post(int argc,char **argv,gboolean success, + const char *repository) +{ + gchar *s,*uri; + struct post *post=NULL; + GError *error=NULL; + if (!argv && !success) + { + /* + * If no --post command has been given, then we want to run the + * program specified in %INSTALL_PREFIX%/etc/pre-inst.post + * However, if the pre-install failed, then that file isn't likely + * to exist (and it's requirements even less so) so we issue an error + * instead. Unfortunately, it's hard to include the error message + * here. It will have been logged in the plover log, but that's not + * much help to users. + */ +#ifndef WIN32 + fprintf(stderr, + "Installation failed: Failed to unpack the main installer\n"); +#else + MessageBox(NULL,"Failed to unpack the main installer", + "Installation failed",MB_ICONERROR|MB_OK); +#endif + return FALSE; + } + if (!argv) + { + post=pre_install_post_new(repository,prefix); + uri=razor_path_to_uri(prefix); + s=g_strconcat(uri,"/etc/pre-inst.post",NULL); + g_free(uri); + pre_install_post_load_uri(post,s,&error); + if (error) + g_debug("Failed to load post configuration from pre-inst.post: %s", + error->message); + g_free(s); + if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT)) + { + /* + * If no post configuration file exists, that's not an error; + * there simply is no post action configured. + */ + g_clear_error(&error); + } + } + if (post && post->argc>0) + pre_install_spawn_sync(post->argv,&error); + else if (argv) + run_post(argc,argv,success,repository,&error); + if (post) + pre_install_post_free(post); + if (error) + { +#ifndef WIN32 + fprintf(stderr,"Error in post: %s\n",error->message); +#else + MessageBox(NULL,error->message,"Error in post",MB_ICONERROR|MB_OK); +#endif + g_error_free(error); + success=FALSE; + } + return success; +} + int main(int argc,char **argv) { gboolean success,uninstall=FALSE,enable_post=FALSE; @@ -573,16 +643,10 @@ success=!!pre_install(repository); #endif } - if (enable_post && !run_post(argc,argv,success,repository,&error)) - { -#ifndef WIN32 - fprintf(stderr,"Error in post: %s\n",error->message); -#else - MessageBox(NULL,error->message,"Error in post",MB_ICONERROR|MB_OK); -#endif - g_error_free(error); - success=FALSE; - } + if (enable_post) + success=pre_install_post(argc,argv,success,repository); + else if (!uninstall) + success=pre_install_post(0,NULL,success,repository); #ifdef WIN32 return success?EXIT_SUCCESS:EXIT_FAILURE; #else