env.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Provide setenv() and unsetenv() on platforms that don't have them.
  3. * From FreeBSD's libc.
  4. */
  5. /*
  6. * Copyright (c) 1987, 1993
  7. * The Regents of the University of California. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the University of
  20. * California, Berkeley and its contributors.
  21. * 4. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. /* $XFree86: xc/programs/xedit/lisp/env.c,v 1.1 2002/03/05 03:52:34 dawes Exp $ */
  38. #include <stdlib.h>
  39. #include <stddef.h>
  40. #include <string.h>
  41. extern char **environ;
  42. extern int setenv(const char *name, const char *value, int overwrite);
  43. extern void unsetenv(const char *name);
  44. static char *
  45. findenv(const char *name, int *offset)
  46. {
  47. int len, i;
  48. const char *np;
  49. char **p, *cp;
  50. if (name == NULL || environ == NULL)
  51. return NULL;
  52. for (np = name; *np && *np != '='; ++np)
  53. continue;
  54. len = np - name;
  55. for (p = environ; (cp = *p) != NULL; ++p) {
  56. for (np = name, i = len; i && *cp; i--)
  57. if (*cp++ != *np++)
  58. break;
  59. if (i == 0 && *cp++ == '=') {
  60. *offset = p - environ;
  61. return cp;
  62. }
  63. }
  64. return NULL;
  65. }
  66. /*
  67. * setenv --
  68. * Set the value of the environmental variable "name" to be
  69. * "value". If overwrite is set, replace any current value.
  70. */
  71. int
  72. setenv(const char *name, const char *value, int overwrite)
  73. {
  74. static char **alloced; /* if allocated space before */
  75. char *c;
  76. int l_value, offset;
  77. if (*value == '=') /* no '=' in value */
  78. ++value;
  79. l_value = strlen(value);
  80. if ((c = findenv(name, &offset))) { /* find if already exists */
  81. if (!overwrite)
  82. return 0;
  83. if (strlen(c) >= l_value) { /* old larger; copy over */
  84. while ((*c++ = *value++))
  85. ;
  86. return 0;
  87. }
  88. } else { /* create new slot */
  89. int cnt;
  90. char **p;
  91. for (p = environ, cnt = 0; *p; ++p, ++cnt)
  92. ;
  93. if (alloced == environ) { /* just increase size */
  94. p = (char **)realloc((char *)environ,
  95. sizeof(char *) * (cnt + 2));
  96. if (!p)
  97. return -1;
  98. alloced = environ = p;
  99. } else { /* get new space */
  100. /* copy old entries into it */
  101. p = malloc(sizeof(char *) * (cnt + 2));
  102. if (!p)
  103. return -1;
  104. memcpy(p, environ, cnt * sizeof(char *));
  105. alloced = environ = p;
  106. }
  107. environ[cnt + 1] = NULL;
  108. offset = cnt;
  109. }
  110. for (c = (char *)name; *c && *c != '='; ++c) /* no '=' in name */
  111. ;
  112. if (!(environ[offset] = /* name + '=' + value */
  113. malloc((int)(c - name) + l_value + 2)))
  114. return -1;
  115. for (c = environ[offset]; (*c = *name++) && *c != '='; ++c)
  116. ;
  117. for (*c++ = '='; (*c++ = *value++); )
  118. ;
  119. return 0;
  120. }
  121. /*
  122. * unsetenv(name) --
  123. * Delete environmental variable "name".
  124. */
  125. void
  126. unsetenv(const char *name)
  127. {
  128. char **p;
  129. int offset;
  130. while (findenv(name, &offset)) /* if set multiple times */
  131. for (p = &environ[offset];; ++p)
  132. if (!(*p = *(p + 1)))
  133. break;
  134. }