pre-inst/pre-inst.c
changeset 96 d2d88f14283e
parent 95 212150407fcc
child 97 55ae076f393c
     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