X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fscript.c;h=d4db8894de860b0b5a40010d7ccb5a05409c2430;hp=55473b1f95e6ea595fe1664740aceefee8684e6e;hb=c2dc3784f127ef6db6e9960a4abecc1aab6f4e31;hpb=3ccdf50beb6b2d3f2730bdc66006b43190537cde diff --git a/src/script.c b/src/script.c index 55473b1f..d4db8894 100644 --- a/src/script.c +++ b/src/script.c @@ -26,8 +26,44 @@ #include "script.h" #include "xalloc.h" +#ifdef HAVE_PUTENV +static void unputenv(const char *p) { + const char *e = strchr(p, '='); + if(!e) + return; + int len = e - p; +#ifndef HAVE_UNSETENV +#ifdef HAVE_MINGW + // Windows requires putenv("FOO=") to unset %FOO% + len++; +#endif +#endif + char var[len + 1]; + strncpy(var, p, len); + var[len] = 0; +#ifdef HAVE_UNSETENV + unsetenv(var); +#else + // We must keep what we putenv() around in memory. + // To do this without memory leaks, keep things in a list and reuse if possible. + static list_t list = {}; + for list_each(char, data, &list) { + if(!strcmp(data, var)) { + putenv(data); + return; + } + } + char *data = xstrdup(var); + list_insert_tail(&list, data); + putenv(data); +#endif +} +#else +static void putenv(const char *p) {} +static void unputenv(const char *p) {} +#endif + bool execute_script(const char *name, char **envp) { -#ifdef HAVE_SYSTEM char scriptname[PATH_MAX]; char *command; @@ -38,9 +74,11 @@ bool execute_script(const char *name, char **envp) { #ifdef HAVE_MINGW if(!*scriptextension) { const char *pathext = getenv("PATHEXT") ?: ".COM;.EXE;.BAT;.CMD"; - char fullname[strlen(scriptname) + strlen(pathext)]; - char *ext = fullname + strlen(scriptname); - strcpy(fullname, scriptname); + size_t pathlen = strlen(pathext); + size_t scriptlen = strlen(scriptname); + char fullname[scriptlen + pathlen + 1]; + char *ext = fullname + scriptlen; + strncpy(fullname, scriptname, sizeof fullname); const char *p = pathext; bool found = false; @@ -51,7 +89,7 @@ bool execute_script(const char *name, char **envp) { ext[q - p] = 0; q++; } else { - strcpy(ext, p); + strncpy(ext, p, pathlen + 1); } if((found = !access(fullname, F_OK))) break; @@ -67,12 +105,10 @@ bool execute_script(const char *name, char **envp) { logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name); -#ifdef HAVE_PUTENV /* Set environment */ for(int i = 0; envp[i]; i++) putenv(envp[i]); -#endif if(scriptinterpreter) xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname); @@ -85,15 +121,8 @@ bool execute_script(const char *name, char **envp) { /* Unset environment */ - for(int i = 0; envp[i]; i++) { - char *e = strchr(envp[i], '='); - if(e) { - char p[e - envp[i] + 1]; - strncpy(p, envp[i], e - envp[i]); - p[e - envp[i]] = '\0'; - putenv(p); - } - } + for(int i = 0; envp[i]; i++) + unputenv(envp[i]); if(status != -1) { #ifdef WEXITSTATUS @@ -116,6 +145,6 @@ bool execute_script(const char *name, char **envp) { logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno)); return false; } -#endif + return true; }