home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / tcp_wrapper-6.3 / environ.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-27  |  4.8 KB  |  225 lines

  1. /*
  2.  * Many systems have putenv() but no setenv(). Other systems have setenv()
  3.  * but no putenv() (MIPS). Still other systems have neither (NeXT). This is a
  4.  * re-implementation that hopefully ends all problems.
  5.  *
  6.  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  7.  */
  8.  
  9. #ifndef lint
  10. static char sccsid[] = "@(#) environ.c 1.2 94/03/23 16:09:46";
  11. #endif
  12.  
  13. /* System libraries. */
  14.  
  15. extern char **environ;
  16. extern char *strchr();
  17. extern char *strcpy();
  18. extern char *strncpy();
  19. extern char *malloc();
  20. extern char *realloc();
  21. extern int strncmp();
  22. extern void free();
  23.  
  24. #ifdef no_memcpy
  25. #define memcpy(d,s,l) bcopy(s,d,l)
  26. #else
  27. extern char *memcpy();
  28. #endif
  29.  
  30. /* Local stuff. */
  31.  
  32. static int addenv();            /* append entry to environment */
  33.  
  34. static int allocated = 0;        /* environ is, or is not, allocated */
  35.  
  36. #define DO_CLOBBER    1
  37.  
  38. /* namelength - determine length of name in "name=whatever" */
  39.  
  40. static int namelength(name)
  41. char   *name;
  42. {
  43.     char   *equal;
  44.  
  45.     equal = strchr(name, '=');
  46.     return ((equal == 0) ? strlen(name) : (equal - name));
  47. }
  48.  
  49. /* findenv - given name, locate name=value */
  50.  
  51. static char **findenv(name, len)
  52. char   *name;
  53. int     len;
  54. {
  55.     char  **envp;
  56.  
  57.     for (envp = environ; envp && *envp; envp++)
  58.     if (strncmp(name, *envp, len) == 0 && (*envp)[len] == '=')
  59.         return (envp);
  60.     return (0);
  61. }
  62.  
  63. /* getenv - given name, locate value */
  64.  
  65. char   *getenv(name)
  66. char   *name;
  67. {
  68.     int     len = namelength(name);
  69.     char  **envp = findenv(name, len);
  70.  
  71.     return (envp ? *envp + len + 1 : 0);
  72. }
  73.  
  74. /* putenv - update or append environment (name,value) pair */
  75.  
  76. int     putenv(nameval)
  77. char   *nameval;
  78. {
  79.     char   *equal = strchr(nameval, '=');
  80.     char   *value = (equal ? equal : "");
  81.  
  82.     return (setenv(nameval, value, DO_CLOBBER));
  83. }
  84.  
  85. /* unsetenv - remove variable from environment */
  86.  
  87. void    unsetenv(name)
  88. char   *name;
  89. {
  90.     char  **envp;
  91.  
  92.     if ((envp = findenv(name, namelength(name))) != 0)
  93.     while (envp[0] = envp[1])
  94.         envp++;
  95. }
  96.  
  97. /* setenv - update or append environment (name,value) pair */
  98.  
  99. int     setenv(name, value, clobber)
  100. char   *name;
  101. char   *value;
  102. int     clobber;
  103. {
  104.     char   *destination;
  105.     char  **envp;
  106.     int     l_name;            /* length of name part */
  107.     int     l_nameval;            /* length of name=value */
  108.  
  109.     /* Permit name= and =value. */
  110.  
  111.     l_name = namelength(name);
  112.     envp = findenv(name, l_name);
  113.     if (envp != 0 && clobber == 0)
  114.     return (0);
  115.     if (*value == '=')
  116.     value++;
  117.     l_nameval = l_name + strlen(value) + 1;
  118.  
  119.     /*
  120.      * Use available memory if the old value is long enough. Never free an
  121.      * old name=value entry because it may not be allocated.
  122.      */
  123.  
  124.     destination = (envp != 0 && strlen(*envp) >= l_nameval) ?
  125.     *envp : malloc(l_nameval + 1);
  126.     if (destination == 0)
  127.     return (-1);
  128.     strncpy(destination, name, l_name);
  129.     destination[l_name] = '=';
  130.     strcpy(destination + l_name + 1, value);
  131.     return ((envp == 0) ? addenv(destination) : (*envp = destination, 0));
  132. }
  133.  
  134. /* cmalloc - malloc and copy block of memory */
  135.  
  136. static char *cmalloc(new_len, old, old_len)
  137. char   *old;
  138. int     old_len;
  139. {
  140.     char   *new = malloc(new_len);
  141.  
  142.     if (new != 0)
  143.     memcpy(new, old, old_len);
  144.     return (new);
  145. }
  146.  
  147. /* addenv - append environment entry */
  148.  
  149. static int addenv(nameval)
  150. char   *nameval;
  151. {
  152.     char  **envp;
  153.     int     n_used;            /* number of environment entries */
  154.     int     l_used;            /* bytes used excl. terminator */
  155.     int     l_need;            /* bytes needed incl. terminator */
  156.  
  157.     for (envp = environ; envp && *envp; envp++)
  158.      /* void */ ;
  159.     n_used = envp - environ;
  160.     l_used = n_used * sizeof(*envp);
  161.     l_need = l_used + 2 * sizeof(*envp);
  162.  
  163.     envp = allocated ?
  164.     (char **) realloc((char *) environ, l_need) :
  165.     (char **) cmalloc(l_need, (char *) environ, l_used);
  166.     if (envp == 0) {
  167.     return (-1);
  168.     } else {
  169.     allocated = 1;
  170.     environ = envp;
  171.     environ[n_used++] = nameval;        /* add new entry */
  172.     environ[n_used] = 0;            /* terminate list */
  173.     return (0);
  174.     }
  175. }
  176.  
  177. #ifdef TEST
  178.  
  179.  /*
  180.   * Stand-alone program for test purposes.
  181.   */
  182.  
  183. /* printenv - display environment */
  184.  
  185. static void printenv()
  186. {
  187.     char  **envp;
  188.  
  189.     for (envp = environ; envp && *envp; envp++)
  190.     printf("%s\n", *envp);
  191. }
  192.  
  193. int     main(argc, argv)
  194. int     argc;
  195. char  **argv;
  196. {
  197.     char   *cp;
  198.     int     changed = 0;
  199.  
  200.     if (argc < 2) {
  201.     printf("usage: %s name[=value]...\n", argv[0]);
  202.     return (1);
  203.     }
  204.     while (--argc && *++argv) {
  205.     if (argv[0][0] == '-') {        /* unsetenv() test */
  206.         unsetenv(argv[0] + 1);
  207.         changed = 1;
  208.     } else if (strchr(argv[0], '=') == 0) {    /* getenv() test */
  209.         cp = getenv(argv[0]);
  210.         printf("%s: %s\n", argv[0], cp ? cp : "not found");
  211.     } else {                /* putenv() test */
  212.         if (putenv(argv[0])) {
  213.         perror("putenv");
  214.         return (1);
  215.         }
  216.         changed = 1;
  217.     }
  218.     }
  219.     if (changed)
  220.     printenv();
  221.     return (0);
  222. }
  223.  
  224. #endif /* TEST */
  225.