X-Git-Url: http://tinc-vpn.org/git/browse?a=blobdiff_plain;ds=sidebyside;f=src%2Fscript.c;h=80c58c042dbf8c14a433bd53ea3f14b1844732f2;hb=3a316823b971396a428f020f401b9fe41252d98d;hp=d4db8894de860b0b5a40010d7ccb5a05409c2430;hpb=25bcdad878eb7349d19ea877fdcc058d4c6b2242;p=tinc diff --git a/src/script.c b/src/script.c index d4db8894..80c58c04 100644 --- a/src/script.c +++ b/src/script.c @@ -1,7 +1,7 @@ /* script.c -- call an external script Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2015 Guus Sliepen + 2000-2017 Guus Sliepen 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 @@ -21,6 +21,7 @@ #include "system.h" #include "conf.h" +#include "device.h" #include "logger.h" #include "names.h" #include "script.h" @@ -63,11 +64,62 @@ static void putenv(const char *p) {} static void unputenv(const char *p) {} #endif -bool execute_script(const char *name, char **envp) { +static const int min_env_size = 10; + +int environment_add(environment_t *env, const char *format, ...) { + if(env->n >= env->size) { + env->size = env->n ? env->n * 2 : min_env_size; + env->entries = xrealloc(env->entries, env->size * sizeof(*env->entries)); + } + + if(format) { + va_list ap; + va_start(ap, format); + vasprintf(&env->entries[env->n], format, ap); + va_end(ap); + } else { + env->entries[env->n] = NULL; + } + + return env->n++; +} + +void environment_update(environment_t *env, int pos, const char *format, ...) { + free(env->entries[pos]); + va_list ap; + va_start(ap, format); + vasprintf(&env->entries[pos], format, ap); + va_end(ap); +} + +void environment_init(environment_t *env) { + env->n = 0; + env->size = min_env_size; + env->entries = xzalloc(env->size * sizeof(*env->entries)); + + if(netname) + environment_add(env, "NETNAME=%s", netname); + if(myname) + environment_add(env, "NAME=%s", myname); + if(device) + environment_add(env, "DEVICE=%s", device); + if(iface) + environment_add(env, "INTERFACE=%s", iface); + if(debug_level >= 0) + environment_add(env, "DEBUG=%d", debug_level); +} + +void environment_exit(environment_t *env) { + for(int i = 0; i < env->n; i++) + free(env->entries[i]); + free(env->entries); +} + +bool execute_script(const char *name, environment_t *env) { char scriptname[PATH_MAX]; char *command; - snprintf(scriptname, sizeof scriptname, "%s" SLASH "%s%s", confbase, name, scriptextension); + snprintf(scriptname, sizeof(scriptname), "%s" SLASH "%s%s", confbase, name, scriptextension); /* First check if there is a script */ @@ -78,7 +130,7 @@ bool execute_script(const char *name, char **envp) { size_t scriptlen = strlen(scriptname); char fullname[scriptlen + pathlen + 1]; char *ext = fullname + scriptlen; - strncpy(fullname, scriptname, sizeof fullname); + strncpy(fullname, scriptname, sizeof(fullname)); const char *p = pathext; bool found = false; @@ -107,8 +159,8 @@ bool execute_script(const char *name, char **envp) { /* Set environment */ - for(int i = 0; envp[i]; i++) - putenv(envp[i]); + for(int i = 0; i < env->n; i++) + putenv(env->entries[i]); if(scriptinterpreter) xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); @@ -121,8 +173,8 @@ bool execute_script(const char *name, char **envp) { /* Unset environment */ - for(int i = 0; envp[i]; i++) - unputenv(envp[i]); + for(int i = 0; i < env->n; i++) + unputenv(env->entries[i]); if(status != -1) { #ifdef WEXITSTATUS