Logo Search packages:      
Sourcecode: mailagent version File versions  Download package

environ.c

/*

 ######  #    #  #    #     #    #####    ####   #    #           ####
 #       ##   #  #    #     #    #    #  #    #  ##   #          #    #
 #####   # #  #  #    #     #    #    #  #    #  # #  #          #
 #       #  # #  #    #     #    #####   #    #  #  # #   ###    #
 #       #   ##   #  #      #    #   #   #    #  #   ##   ###    #    #
 ######  #    #    ##       #    #    #   ####   #    #   ###     ####

      Environment setting.
*/

/*
 * $Id: environ.c 58 2008-08-19 08:44:07Z rmanfredi $
 *
 *  Copyright (c) 1990-2006, Raphael Manfredi
 *  
 *  You may redistribute only under the terms of the Artistic License,
 *  as specified in the README file that comes with the distribution.
 *  You may reuse parts of this distribution only within the terms of
 *  that same Artistic License; a copy of which may be found at the root
 *  of the source tree for mailagent 3.0.
 *
 * $Log: environ.c,v $
 * Revision 3.0.1.2  1996/12/24  13:52:05  ram
 * patch45: new get_env() routine, plus typo fixes
 * patch45: make sure new environment lines are smaller than MAX_STRING
 *
 * Revision 3.0.1.1  1995/08/07  16:08:02  ram
 * patch37: removed useless local variable declaration
 *
 * Revision 3.0  1993/11/29  13:48:07  ram
 * Baseline for mailagent 3.0 netwide release.
 *
 */

#include "config.h"
#include "portable.h"
#include "logfile.h"
#include "hash.h"
#include "msg.h"
#include <stdio.h>

#ifdef I_STRING
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef I_STDLIB
#include <stdlib.h>
#else
#ifdef I_MALLOC
#include <malloc.h>
#else
extern char *malloc();                    /* Memory allocation */
#endif
#endif      /* I_STDLIB */
#include "confmagic.h"

#define ENV_VARS  200                     /* An average number of environment vars */
#define MAX_STRING      4096              /* Maximum size for an environment value */

/* The environment is stored as an associative array: the key is the variable's
 * name, and we store the value as the associated value, of course. This is
 * not suitable for direct passing to a child, but it eases the environment
 * modifications.
 */
private struct htable henv;               /* The associative array for env */

extern char *strsave();                   /* String saving */

public void print_env(fd, envp)
FILE *fd;
char **envp;
{
      /* Print the environment held in 'envp' on file 'fd'. This is mainly
       * intended for debug purposes.
       */

      while (*envp)
            fprintf(fd, "%s\n", *envp++);
}

public int init_env(envp)
char **envp;
{
      /* Initializes the associative array with the current environment. Returns
       * 0 if ok, -1 if failed due to a lack of memory.
       */

      char env_line[MAX_STRING + 1];      /* The environment line */
      char *ptr;                                /* Pointer inside env_line */
      char *env;                                /* The current environment line */

      if (-1 == ht_create(&henv, ENV_VARS))
            return -1;                          /* Cannot create H table */

      while ((env = *envp++)) {
            strncpy(env_line, env, MAX_STRING);
            ptr = index(env_line, '=');
            if (ptr == (char *) 0) {
                  add_log(6, "WARNING bad environment line");
                  continue;
            }
            *ptr = '\0';                        /* Before '=' lies the key */
            if ((char *) 0 == ht_put(&henv, env_line, ptr + 1)) {
                  add_log(4, "ERROR cannot record environment any more");
                  return -1;
            }
      }

      return 0;   /* Ok */
}

public int append_env(key, value)
char *key;
char *value;
{
      /* Appends 'value' at the end of the environment variable 'key', if it
       * already exists, otherwise create it with that value.
       * Returns 0 for success, -1 for failure.
       */
      
      char env_line[MAX_STRING + 1];      /* The environment line */
      char *cval;                               /* Current value */

      cval = ht_value(&henv, key);
      if (cval == (char *) 0) {
            if ((char *) 0 == ht_put(&henv, key, value)) {
                  add_log(1, "ERROR cannot insert environment variable '%s'", key);
                  return -1;                    /* Insertion failed */
            }
            return 0;                           /* Insertion ok */
      }

      strncpy(env_line, cval, MAX_STRING);
      if (strlen(env_line) + strlen(value) > MAX_STRING) {
            add_log(1, "ERROR cannot append to environment variable '%s'", key);
            return -1;
      }
      strcat(env_line, value);
      if ((char *) 0 == ht_force(&henv, key, env_line)) {
            add_log(1, "ERROR cannot update environment variable '%s'", key);
            return -1;
      }

      return 0;   /* Ok */
}

public int prepend_env(key, value)
char *key;
char *value;
{
      /* Prepends 'value' at the head of the environment variable 'key', if it
       * already exists, otherwise create it with that value.
       * Returns 0 for success, -1 for failure.
       */
      
      char env_line[MAX_STRING + 1];      /* The environment line */
      char *cval;                               /* Current value */

      cval = ht_value(&henv, key);
      if (cval == (char *) 0) {
            if ((char *) 0 == ht_put(&henv, key, value)) {
                  add_log(1, "ERROR cannot insert environment variable '%s'", key);
                  return -1;                    /* Insertion failed */
            }
            return 0;                           /* Insertion ok */
      }

      strncpy(env_line, value, MAX_STRING);
      if (strlen(env_line) + strlen(cval) > MAX_STRING) {
            add_log(1, "ERROR cannot prepend to environment variable '%s'", key);
            return -1;
      }
      strcat(env_line, cval);
      if ((char *) 0 == ht_force(&henv, key, env_line)) {
            add_log(1, "ERROR cannot update environment variable '%s'", key);
            return -1;
      }

      return 0;   /* Ok */
}

public int set_env(key, value)
char *key;
char *value;
{
      /* Set environment value 'key' and return 0 for success, -1 for failure. */

      char *cval;                               /* Current value */

      cval = ht_value(&henv, key);
      if (cval == (char *) 0) {
            if ((char *) 0 == ht_put(&henv, key, value)) {
                  add_log(1, "ERROR cannot insert environment variable '%s'", key);
                  return -1;                    /* Insertion failed */
            }
            return 0;                           /* Insertion ok */
      }

      if ((char *) 0 == ht_force(&henv, key, value)) {
            add_log(1, "ERROR cannot update environment variable '%s'", key);
            return -1;
      }

      return 0;   /* Ok */
}

public char *get_env(key)
char *key;
{
      return ht_value(&henv, key);  /* Pointer to string value, or null */
}

public char **make_env()
{
      /* Create the environment pointer suitable for the execle() system call.
       * Return a null pointer if there is not enough memory to create the
       * environment.
       */

      char env_line[MAX_STRING + 1];      /* The environment line */
      char **envp;                              /* The environment pointer returned */
      char **ptr;                               /* Pointer in the environment */
      int nb_line;                              /* Number of lines */

      nb_line = ht_count(&henv) + 1;      /* Envp ends with a null pointer */
      if (nb_line == 0) {
            add_log(6, "NOTICE environment is empty");
            return (char **) 0;
      }
      envp = (char **) malloc(nb_line * sizeof(char *));
      if (envp == (char **) 0)
            fatal("out of memory");
      
      if (-1 == ht_start(&henv))
            fatal("environment H table botched");
      
      ptr = envp;
      for (ptr = envp; --nb_line > 0; (void) ht_next(&henv), ptr++) {
            char *key = ht_ckey(&henv);
            char *value = ht_cvalue(&henv);
            if ((strlen(key) + strlen(value) + 1) > MAX_STRING) {
                  add_log(1, "ERROR can't propagate environment variable %s", key);
                  fatal("environment line too big");
            }
            sprintf(env_line, "%s=%s", key, value);         /* key=value */
            *ptr = strsave(env_line);
            if (*ptr == (char *) 0)
                  fatal("no more memory for environment");
      }

      *ptr = (char *) 0;                        /* Environment is NULL terminated */

      return envp;                              /* Pointer to new environment */
}


Generated by  Doxygen 1.6.0   Back to index