aboutsummaryrefslogtreecommitdiff
path: root/src/progman.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/progman.c')
-rw-r--r--src/progman.c310
1 files changed, 50 insertions, 260 deletions
diff --git a/src/progman.c b/src/progman.c
index 85670f2..b75a2db 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -390,6 +390,14 @@ redirect_to_file (struct prog *master, int stream)
master->v.p.comp->redir[stream].v.file,
strerror (errno));
}
+ /* Position to the end of file */
+ if (lseek (fd, 0, SEEK_END) == -1)
+ {
+ if (errno != ESPIPE)
+ logmsg (LOG_ERR, "lseek(%s): %s",
+ master->v.p.comp->redir[stream].v.file,
+ strerror (errno));
+ }
return fd;
}
@@ -604,10 +612,6 @@ conn_class_remove (struct conn_class *pcclass)
}
-extern char **environ; /* Environment */
-static size_t envsize; /* Size of environ. If it is not 0, then we
- have allocated space for the environ. */
-
#define ENV_PROTO "PROTO"
#define ENV_SOCKTYPE "SOCKTYPE"
#define ENV_LOCALIP "LOCALIP"
@@ -616,254 +620,30 @@ static size_t envsize; /* Size of environ. If it is not 0, then we
#define ENV_REMOTEIP "REMOTEIP"
#define ENV_REMOTEPORT "REMOTEPORT"
#define ENV_REMOTEHOST "REMOTEHOST"
-static char *sockenv_hint[] = {
- "-" ENV_PROTO,
- "-" ENV_SOCKTYPE,
- "-" ENV_LOCALIP,
- "-" ENV_LOCALPORT,
- "-" ENV_LOCALHOST,
- "-" ENV_REMOTEIP,
- "-" ENV_REMOTEPORT,
- "-" ENV_REMOTEHOST,
+static char *sockenv_var[] = {
+ ENV_PROTO,
+ ENV_SOCKTYPE,
+ ENV_LOCALIP,
+ ENV_LOCALPORT,
+ ENV_LOCALHOST,
+ ENV_REMOTEIP,
+ ENV_REMOTEPORT,
+ ENV_REMOTEHOST,
NULL
};
-#define DEBUG_ENVIRON(l) \
- do \
- if (debug_level >= (l)) \
- { \
- int i; \
- logmsg_printf (LOG_DEBUG, "environment: "); \
- for (i = 0; environ[i]; i++) \
- logmsg_printf (LOG_DEBUG, "%s ", environ[i]); \
- logmsg_printf (LOG_DEBUG, "\n"); \
- } \
- while (0)
-
-static void
-add_env (const char *name, const char *value)
-{
- size_t i;
- size_t namelen = strlen (name);
- char *p;
-
- for (i = 0; environ[i]; i++)
- {
- if (!strncmp (environ[i], name, namelen) && environ[i][namelen] == '=')
- break;
- }
-
- if (environ[i] == NULL)
- {
- if (envsize == 0)
- {
- char **new_env;
-
- envsize = i + 4;
- new_env = grecs_calloc (envsize, sizeof new_env[0]);
- for (i = 0; (new_env[i] = environ[i]); i++)
- ;
- environ = new_env;
- }
- else if (i == envsize)
- {
- envsize += 4;
- environ = grecs_realloc (environ,
- envsize * sizeof environ[0]);
- }
- environ[i+1] = NULL;
- }
-
- if (!value)
- value = "";
- p = grecs_malloc (namelen + 1 + strlen (value) + 1);
- strcpy (p, name);
- p[namelen] = '=';
- strcpy (p + namelen + 1, value);
- environ[i] = p;
-}
-
-/* Find variable NAME in environment ENV.
- On success, store the index of the ENV slot in *IDX,
- the offset of the value (position right past '=') in *VALOFF, and
- return 0 (IDX and/or VALOFF can be NULL, if that info is not needed).
- Return -1 if NAME was not found. */
-static int
-find_env_pos (char **env, char *name, size_t *idx, size_t *valoff)
+static inline void
+debug_environ (struct prog *prog, int l)
{
- size_t nlen = strcspn (name, "+=");
- size_t i;
-
- for (i = 0; env[i]; i++)
+ if (debug_level >= l)
{
- size_t elen = strcspn (env[i], "=");
- if (elen == nlen && memcmp (name, env[i], nlen) == 0)
- {
- if (idx)
- *idx = i;
- if (valoff)
- *valoff = elen + 1;
- return 0;
- }
- }
- return -1;
-}
-
-/* Find variable NAME in environment ENV.
- On success, return pointer to the variable assignment (if VAL is 0),
- or to the value (if VAL is 1).
- Return NULL if NAME is not present in ENV. */
-static char *
-find_env_ptr (char **env, char *name, int val)
-{
- size_t i, j;
- if (find_env_pos (env, name, &i, &j))
- return NULL;
- return val ? env[i] + j : env[i];
-}
-
-/* Return 1 if ENV contains a matching unset statement for variable NAME. */
-static int
-var_is_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 (const char *name, size_t namelen, const char *a, const char *b)
-{
- char *res;
- size_t len;
-
- if (a && b)
- {
- res = grecs_malloc (namelen + 1 + strlen (a) + strlen (b) + 1);
- strcpy (res + namelen + 1, a);
- strcat (res + namelen + 1, b);
- }
- else if (a)
- {
- len = strlen (a);
- if (c_ispunct (a[len-1]))
- len--;
- res = grecs_malloc (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++;
- len = strlen (b);
- res = grecs_malloc (namelen + 1 + len + 1);
- strcpy (res + namelen + 1, b);
- }
- memcpy (res, name, namelen);
- res[namelen] = '=';
- return res;
-}
-
-static void
-environ_setup (char **hint)
-{
- char **old_env = environ;
- char **new_env;
- size_t count, i, j, n;
-
- if (!hint)
- return;
-
- if (strcmp (hint[0], "-") == 0)
- {
- old_env = NULL;
- hint++;
- }
-
- /* Count new environment size */
- count = 0;
- if (old_env)
- for (i = 0; old_env[i]; i++)
- count++;
-
- for (i = 0; hint[i]; i++)
- count++;
-
- /* Allocate new environment. */
- new_env = grecs_calloc (count + 1, sizeof new_env[0]);
-
- /* Populate the environment. */
- n = 0;
-
- if (old_env)
- for (i = 0; old_env[i]; i++)
- {
- if (!var_is_unset (hint, old_env[i]))
- new_env[n++] = old_env[i];
- }
-
- for (i = 0; hint[i]; i++)
- {
- char *p;
-
- if (hint[i][0] == '-')
- {
- /* Skip unset directives. */
- continue;
- }
-
- /* Find the slot for the variable. Use next available
- slot if there's no such variable in new_env */
- if (find_env_pos (new_env, hint[i], &j, NULL))
- j = n;
-
- if ((p = strchr (hint[i], '=')))
- {
- if (p == hint[i])
- continue; /* Ignore erroneous entry */
- if (p[-1] == '+')
- new_env[j] = env_concat (hint[i], p - hint[i] - 1,
- find_env_ptr (environ, hint[i], 1),
- p + 1);
- else if (p[1] == '+')
- new_env[j] = env_concat (hint[i], p - hint[i],
- p + 2,
- find_env_ptr (environ, hint[i], 1));
- else
- new_env[j] = hint[i];
- }
- else if ((p = find_env_ptr (environ, hint[i], 0)))
- new_env[j] = p;
- else
- continue;
-
- /* Adjust environment size */
- if (j == n)
- ++n;
+ int i;
+ char **env = environ_ptr (prog->v.p.env);
+ logmsg_printf (LOG_DEBUG, "environment: ");
+ for (i = 0; env[i]; i++)
+ logmsg_printf (LOG_DEBUG, "%s ", env[i]);
+ logmsg_printf (LOG_DEBUG, "\n");
}
- new_env[n] = NULL;
-
- if (envsize)
- free (environ);
-
- environ = new_env;
- envsize = count + 1;
}
/* Pass socket information in environment variables. */
@@ -884,7 +664,7 @@ prog_sockenv (struct prog *prog)
if (socket_type_to_str (prog->v.p.comp->socket_type, &proto))
proto = umaxtostr (prog->v.p.comp->socket_type, buf);
- add_env (ENV_SOCKTYPE, proto);
+ environ_set (prog->v.p.env, ENV_SOCKTYPE, proto);
if (prog->v.p.comp->socket_url)
proto = prog->v.p.comp->socket_url->proto_s;
@@ -893,7 +673,7 @@ prog_sockenv (struct prog *prog)
else if (ISCF_TCPMUX (prog->v.p.comp->flags))
proto = "TCP";
- add_env (ENV_PROTO, proto);
+ environ_set (prog->v.p.env, ENV_PROTO, proto);
if (getsockname (prog->v.p.socket,
(struct sockaddr *) &sa_server, &len) < 0)
@@ -902,10 +682,10 @@ prog_sockenv (struct prog *prog)
{
p = inet_ntoa (sa_server.s_in.sin_addr);
if (p)
- add_env (ENV_LOCALIP, p);
+ environ_set (prog->v.p.env, ENV_LOCALIP, p);
p = umaxtostr (ntohs (sa_server.s_in.sin_port), buf);
- add_env (ENV_LOCALPORT, p);
+ environ_set (prog->v.p.env, ENV_LOCALPORT, p);
if (prog->v.p.comp->flags & CF_RESOLVE)
{
@@ -914,7 +694,7 @@ prog_sockenv (struct prog *prog)
AF_INET)) == NULL)
logmsg (LOG_WARNING, "gethostbyaddr: %s", strerror (errno));
else
- add_env (ENV_LOCALHOST, host->h_name);
+ environ_set (prog->v.p.env, ENV_LOCALHOST, host->h_name);
}
}
@@ -922,10 +702,10 @@ prog_sockenv (struct prog *prog)
{
p = inet_ntoa (sa_client->s_in.sin_addr);
if (p)
- add_env (ENV_REMOTEIP, p);
+ environ_set (prog->v.p.env, ENV_REMOTEIP, p);
p = umaxtostr (ntohs (sa_client->s_in.sin_port), buf);
- add_env (ENV_REMOTEPORT, p);
+ environ_set (prog->v.p.env, ENV_REMOTEPORT, p);
if (prog->v.p.comp->flags & CF_RESOLVE)
{
@@ -935,11 +715,11 @@ prog_sockenv (struct prog *prog)
logmsg (LOG_WARNING, "gethostbyaddr: %s",
strerror (errno));
else
- add_env (ENV_REMOTEHOST, host->h_name);
+ environ_set (prog->v.p.env, ENV_REMOTEHOST, host->h_name);
}
}
/* FIXME: $REMOTEINFO ? */
- DEBUG_ENVIRON (4);
+ debug_environ (prog, 4);
}
static int
@@ -1036,12 +816,21 @@ prog_start_prologue (struct prog *prog)
prog_tag (prog), prog->v.p.comp->dir, strerror (errno));
}
- environ_setup (prog->v.p.comp->env ?
- prog->v.p.comp->env :
- ((prog->v.p.comp->flags & CF_SOCKENV) ? sockenv_hint : NULL));
+ prog->v.p.env = environ_create (environ);
+ if (prog->v.p.comp->flags & CF_SOCKENV)
+ {
+ size_t i;
+ for (i = 0; sockenv_var[i]; i++)
+ environ_unset (prog->v.p.env, sockenv_var[i]);
+ }
+ envop_exec (prog->v.p.comp->envop, prog->v.p.env);
if (init_process)
- environ_setup (sysvinit_environ_hint);
- DEBUG_ENVIRON (4);
+ {
+ size_t i;
+ for (i = 0; sysvinit_environ_hint[i]; i++)
+ environ_add (prog->v.p.env, sysvinit_environ_hint[i]);
+ }
+ debug_environ (prog, 4);
pies_priv_setup (&prog->v.p.comp->privs);
if (prog->v.p.comp->umask)
@@ -1066,6 +855,7 @@ prog_start_prologue (struct prog *prog)
static void
prog_execute (struct prog *prog)
{
+ environ = environ_ptr (prog->v.p.env);
if (prog->v.p.comp->builtin)
{
mf_proctitle_format ("inetd %s",

Return to:

Send suggestions and report system problems to the System administrator.