diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-10-15 18:22:39 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-10-15 18:22:39 +0000 |
commit | 5699c9bba69675f2d5aeca5a818027c45bb22222 (patch) | |
tree | 5360bf28444fece228ddeb3979965c317e860ba3 /pies | |
parent | 904da6ae728ca85875a5b793aab9b140219d84f4 (diff) | |
download | pies-5699c9bba69675f2d5aeca5a818027c45bb22222.tar.gz pies-5699c9bba69675f2d5aeca5a818027c45bb22222.tar.bz2 |
* pies/progman.c (env_setup): Port new implementation from Rush.
* gnulib.modules: Add c-ctype
* mtasim/mtasim.c, pies/pies.h, pmult/pmult.c, lib/parsetime.c,
mfd/lex.l, mfd/gram.y, mfd/mailfromd.h, mfd/spf.c,
mfd/bi_sprintf.m4, mfd/bi_io.m4, mfd/pp.c, mfd/main.c: Use c-ctype,
instead of ctype.
Diffstat (limited to 'pies')
-rw-r--r-- | pies/pies.h | 1 | ||||
-rw-r--r-- | pies/progman.c | 115 |
2 files changed, 96 insertions, 20 deletions
diff --git a/pies/pies.h b/pies/pies.h index 5f3aebc..e89408b 100644 --- a/pies/pies.h +++ b/pies/pies.h @@ -40,6 +40,7 @@ #include <mailutils/syslog.h> #include "xalloc.h" +#include "c-ctype.h" #include "libmf.h" #define RETR_OUT 0 diff --git a/pies/progman.c b/pies/progman.c index 724ff12..eebcc96 100644 --- a/pies/progman.c +++ b/pies/progman.c @@ -359,22 +359,77 @@ open_retranslator (struct prog *master, int type) extern char **environ; static char * -find_env (char *name) +find_env(char *name, int val) { - int nlen = strlen (name); + int nlen = strcspn(name, "+="); int i; for (i = 0; environ[i]; i++) { - char *p = strchr (environ[i], '='); - int elen = p - environ[i]; - if (elen == nlen && memcmp (name, environ[i], nlen) == 0) - return environ[i]; + size_t elen = strcspn(environ[i], "="); + if (elen == nlen && memcmp(name, environ[i], nlen) == 0) + return val ? environ[i] + elen + 1 : environ[i]; } return NULL; } -static void +static int +locate_unset(char **env, const char *name) +{ + int i; + int nlen = strcspn(name, "="); + + for (i = 0; env[i]; i++) + { + if (env[i][0] == '-') + { + size_t elen = strcspn(env[i] + 1, "="); + if (elen == nlen && memcmp(name, env[i] + 1, nlen) == 0) + { + if (env[i][nlen + 1]) + return strcmp(name + nlen, env[i] + 1 + nlen) == 0; + else + return 1; + } + } + } + return 0; +} + +static char * +env_concat (char *name, size_t namelen, char *a, char *b) +{ + char *res; + size_t len; + + if (a && b) + { + res = xmalloc (namelen + 1 + strlen (a) + strlen (b) + 1); + strcpy (res + namelen + 1, a); + strcat (res, b); + } + else if (a) + { + len = strlen (a); + if (c_ispunct (a[len-1])) + len--; + res = xmalloc (namelen + 1 + len + 1); + memcpy (res + namelen + 1, a, len); + res[namelen + 1 + len] = 0; + } + else /* if (a == NULL) */ + { + if (c_ispunct (b[0])) + b++; + res = xmalloc (namelen + 1 + len + 1); + strcpy (res + namelen + 1, b); + } + memcpy (res, name, namelen); + res[namelen] = '='; + return res; +} + +static char ** env_setup (char **env) { char **old_env = environ; @@ -382,47 +437,67 @@ env_setup (char **env) int count, i, n; if (!env) - return; + return old_env; if (strcmp (env[0], "-") == 0) { old_env = NULL; env++; } - + /* Count new environment size */ count = 0; if (old_env) - for (; old_env[count]; count++) - ; + for (i = 0; old_env[i]; i++) + count++; - for (; env[count]; count++) - ; + for (i = 0; env[i]; i++) + count++; /* Allocate the new environment. */ new_env = xcalloc (count + 1, sizeof new_env[0]); - + /* Populate the environment. */ n = 0; if (old_env) for (i = 0; old_env[i]; i++) - new_env[n++] = old_env[i]; + { + if (!locate_unset (env, old_env[i])) + new_env[n++] = old_env[i]; + } for (i = 0; env[i]; i++) { - if (strchr (env[i], '=')) - new_env[n++] = env[i]; + char *p; + + if (env[i][0] == '-') + { + /* Skip unset directives. */ + continue; + } + if ((p = strchr (env[i], '='))) + { + if (p == env[i]) + continue; /* Ignore erroneous entry */ + if (p[-1] == '+') + new_env[n++] = env_concat (env[i], p - env[i] - 1, + find_env(env[i], 1), p + 1); + else if (p[1] == '+') + new_env[n++] = env_concat (env[i], p - env[i], + p + 2, find_env(env[i], 1)); + else + new_env[n++] = env[i]; + } else { - char *p = find_env (env[i]); + p = find_env (env[i], 0); if (p) new_env[n++] = p; } } new_env[n] = NULL; - /* FIXME: The old environment is not freed. Should it be? */ - environ = new_env; + return new_env; } static void |