1.1 --- a/pre-inst/pre-inst.c Tue Jul 14 13:17:21 2020 +0100
1.2 +++ b/pre-inst/pre-inst.c Wed Jul 15 11:54:06 2020 +0100
1.3 @@ -1,5 +1,5 @@
1.4 /*
1.5 - * Copyright (C) 2014 J. Ali Harlow <ali@juiblex.co.uk>
1.6 + * Copyright (C) 2014, 2020 J. Ali Harlow <ali@juiblex.co.uk>
1.7 *
1.8 * This program is free software; you can redistribute it and/or modify
1.9 * it under the terms of the GNU General Public License as published by
1.10 @@ -44,6 +44,7 @@
1.11 #else /* WIN32 */
1.12 #include <ftw.h>
1.13 #endif /* WIN32 */
1.14 +#include "post.h"
1.15
1.16 #ifdef WIN32
1.17 /* Under WIN32, g_spawn requires a helper program which we'd rather avoid */
1.18 @@ -337,6 +338,47 @@
1.19
1.20 #endif /* defined(WIN32) && !defined(USE_G_SPAWN) */
1.21
1.22 +gboolean pre_install_spawn_sync(char **argv,GError **error)
1.23 +{
1.24 + GError *tmp_error=NULL;
1.25 +#ifdef USE_G_SPAWN
1.26 + gchar *standard_output,*standard_error;
1.27 + int exit_status;
1.28 + if (!g_spawn_sync(NULL,argv,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL,
1.29 + &standard_output,&standard_error,&exit_status,&tmp_error))
1.30 + {
1.31 + fprintf(stderr,"Failed to start post command\n");
1.32 + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[0]);
1.33 + return FALSE;
1.34 + }
1.35 + if (standard_output && *standard_output)
1.36 + {
1.37 + printf("Output from post command %s:\n",argv[0]);
1.38 + fputs(standard_output,stdout);
1.39 + }
1.40 + g_free(standard_output);
1.41 + if (standard_error && *standard_error)
1.42 + {
1.43 + printf("Error output from post command %s:\n",argv[0]);
1.44 + fputs(standard_error,stdout);
1.45 + }
1.46 + g_free(standard_error);
1.47 + if (!g_spawn_check_exit_status(exit_status,&tmp_error))
1.48 + {
1.49 + fprintf(stderr,"post command failed\n");
1.50 + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[0]);
1.51 + return FALSE;
1.52 + }
1.53 +#else
1.54 + if (!spawn_sync(argv,&tmp_error))
1.55 + {
1.56 + g_propagate_prefixed_error(error,tmp_error,"%s: ",argv[0]);
1.57 + return FALSE;
1.58 + }
1.59 +#endif
1.60 + return TRUE;
1.61 +}
1.62 +
1.63 /*
1.64 * Run a command after completing request.
1.65 *
1.66 @@ -354,10 +396,6 @@
1.67 char *s;
1.68 gchar *expanded;
1.69 gchar **post_argv;
1.70 -#ifdef USE_G_SPAWN
1.71 - gchar *standard_output,*standard_error;
1.72 - int exit_status;
1.73 -#endif
1.74 GError *tmp_error=NULL;
1.75 if (argc<2)
1.76 {
1.77 @@ -401,40 +439,7 @@
1.78 post_argv[i]=expanded;
1.79 }
1.80 }
1.81 -#ifdef USE_G_SPAWN
1.82 - if (!g_spawn_sync(NULL,post_argv,NULL,G_SPAWN_SEARCH_PATH,NULL,NULL,
1.83 - &standard_output,&standard_error,&exit_status,&tmp_error))
1.84 - {
1.85 - fprintf(stderr,"Failed to start post command\n");
1.86 - g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
1.87 - return FALSE;
1.88 - }
1.89 - if (standard_output && *standard_output)
1.90 - {
1.91 - printf("Output from post command %s:\n",post_argv[0]);
1.92 - fputs(standard_output,stdout);
1.93 - }
1.94 - g_free(standard_output);
1.95 - if (standard_error && *standard_error)
1.96 - {
1.97 - printf("Error output from post command %s:\n",post_argv[0]);
1.98 - fputs(standard_error,stdout);
1.99 - }
1.100 - g_free(standard_error);
1.101 - if (!g_spawn_check_exit_status(exit_status,&tmp_error))
1.102 - {
1.103 - fprintf(stderr,"post command failed\n");
1.104 - g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
1.105 - return FALSE;
1.106 - }
1.107 -#else
1.108 - if (!spawn_sync(post_argv,&tmp_error))
1.109 - {
1.110 - g_propagate_prefixed_error(error,tmp_error,"%s: ",post_argv[0]);
1.111 - return FALSE;
1.112 - }
1.113 -#endif
1.114 - return TRUE;
1.115 + return pre_install_spawn_sync(post_argv,error);
1.116 }
1.117
1.118 #ifdef WIN32
1.119 @@ -498,6 +503,71 @@
1.120 return uri;
1.121 }
1.122
1.123 +gboolean pre_install_post(int argc,char **argv,gboolean success,
1.124 + const char *repository)
1.125 +{
1.126 + gchar *s,*uri;
1.127 + struct post *post=NULL;
1.128 + GError *error=NULL;
1.129 + if (!argv && !success)
1.130 + {
1.131 + /*
1.132 + * If no --post command has been given, then we want to run the
1.133 + * program specified in %INSTALL_PREFIX%/etc/pre-inst.post
1.134 + * However, if the pre-install failed, then that file isn't likely
1.135 + * to exist (and it's requirements even less so) so we issue an error
1.136 + * instead. Unfortunately, it's hard to include the error message
1.137 + * here. It will have been logged in the plover log, but that's not
1.138 + * much help to users.
1.139 + */
1.140 +#ifndef WIN32
1.141 + fprintf(stderr,
1.142 + "Installation failed: Failed to unpack the main installer\n");
1.143 +#else
1.144 + MessageBox(NULL,"Failed to unpack the main installer",
1.145 + "Installation failed",MB_ICONERROR|MB_OK);
1.146 +#endif
1.147 + return FALSE;
1.148 + }
1.149 + if (!argv)
1.150 + {
1.151 + post=pre_install_post_new(repository,prefix);
1.152 + uri=razor_path_to_uri(prefix);
1.153 + s=g_strconcat(uri,"/etc/pre-inst.post",NULL);
1.154 + g_free(uri);
1.155 + pre_install_post_load_uri(post,s,&error);
1.156 + if (error)
1.157 + g_debug("Failed to load post configuration from pre-inst.post: %s",
1.158 + error->message);
1.159 + g_free(s);
1.160 + if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT))
1.161 + {
1.162 + /*
1.163 + * If no post configuration file exists, that's not an error;
1.164 + * there simply is no post action configured.
1.165 + */
1.166 + g_clear_error(&error);
1.167 + }
1.168 + }
1.169 + if (post && post->argc>0)
1.170 + pre_install_spawn_sync(post->argv,&error);
1.171 + else if (argv)
1.172 + run_post(argc,argv,success,repository,&error);
1.173 + if (post)
1.174 + pre_install_post_free(post);
1.175 + if (error)
1.176 + {
1.177 +#ifndef WIN32
1.178 + fprintf(stderr,"Error in post: %s\n",error->message);
1.179 +#else
1.180 + MessageBox(NULL,error->message,"Error in post",MB_ICONERROR|MB_OK);
1.181 +#endif
1.182 + g_error_free(error);
1.183 + success=FALSE;
1.184 + }
1.185 + return success;
1.186 +}
1.187 +
1.188 int main(int argc,char **argv)
1.189 {
1.190 gboolean success,uninstall=FALSE,enable_post=FALSE;
1.191 @@ -573,16 +643,10 @@
1.192 success=!!pre_install(repository);
1.193 #endif
1.194 }
1.195 - if (enable_post && !run_post(argc,argv,success,repository,&error))
1.196 - {
1.197 -#ifndef WIN32
1.198 - fprintf(stderr,"Error in post: %s\n",error->message);
1.199 -#else
1.200 - MessageBox(NULL,error->message,"Error in post",MB_ICONERROR|MB_OK);
1.201 -#endif
1.202 - g_error_free(error);
1.203 - success=FALSE;
1.204 - }
1.205 + if (enable_post)
1.206 + success=pre_install_post(argc,argv,success,repository);
1.207 + else if (!uninstall)
1.208 + success=pre_install_post(0,NULL,success,repository);
1.209 #ifdef WIN32
1.210 return success?EXIT_SUCCESS:EXIT_FAILURE;
1.211 #else