143f32c10Smrg/* 243f32c10Smrg * Provide setenv() and unsetenv() on platforms that don't have them. 343f32c10Smrg * From FreeBSD's libc. 443f32c10Smrg */ 543f32c10Smrg 643f32c10Smrg/* 743f32c10Smrg * Copyright (c) 1987, 1993 843f32c10Smrg * The Regents of the University of California. All rights reserved. 943f32c10Smrg * 1043f32c10Smrg * Redistribution and use in source and binary forms, with or without 1143f32c10Smrg * modification, are permitted provided that the following conditions 1243f32c10Smrg * are met: 1343f32c10Smrg * 1. Redistributions of source code must retain the above copyright 1443f32c10Smrg * notice, this list of conditions and the following disclaimer. 1543f32c10Smrg * 2. Redistributions in binary form must reproduce the above copyright 1643f32c10Smrg * notice, this list of conditions and the following disclaimer in the 1743f32c10Smrg * documentation and/or other materials provided with the distribution. 1843f32c10Smrg * 3. All advertising materials mentioning features or use of this software 1943f32c10Smrg * must display the following acknowledgement: 2043f32c10Smrg * This product includes software developed by the University of 2143f32c10Smrg * California, Berkeley and its contributors. 2243f32c10Smrg * 4. Neither the name of the University nor the names of its contributors 2343f32c10Smrg * may be used to endorse or promote products derived from this software 2443f32c10Smrg * without specific prior written permission. 2543f32c10Smrg * 2643f32c10Smrg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2743f32c10Smrg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2843f32c10Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2943f32c10Smrg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3043f32c10Smrg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3143f32c10Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3243f32c10Smrg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3343f32c10Smrg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3443f32c10Smrg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3543f32c10Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3643f32c10Smrg * SUCH DAMAGE. 3743f32c10Smrg */ 3843f32c10Smrg 3943f32c10Smrg/* $XFree86: xc/programs/xedit/lisp/env.c,v 1.1 2002/03/05 03:52:34 dawes Exp $ */ 4043f32c10Smrg 4143f32c10Smrg 4243f32c10Smrg#include <stdlib.h> 4343f32c10Smrg#include <stddef.h> 4443f32c10Smrg#include <string.h> 4543f32c10Smrg 4643f32c10Smrgextern char **environ; 4743f32c10Smrg 4843f32c10Smrgextern int setenv(const char *name, const char *value, int overwrite); 4943f32c10Smrgextern void unsetenv(const char *name); 5043f32c10Smrg 5143f32c10Smrgstatic char * 5243f32c10Smrgfindenv(const char *name, int *offset) 5343f32c10Smrg{ 5443f32c10Smrg int len, i; 5543f32c10Smrg const char *np; 5643f32c10Smrg char **p, *cp; 5743f32c10Smrg 5843f32c10Smrg if (name == NULL || environ == NULL) 5943f32c10Smrg return NULL; 6043f32c10Smrg 6143f32c10Smrg for (np = name; *np && *np != '='; ++np) 6243f32c10Smrg continue; 6343f32c10Smrg len = np - name; 6443f32c10Smrg for (p = environ; (cp = *p) != NULL; ++p) { 6543f32c10Smrg for (np = name, i = len; i && *cp; i--) 6643f32c10Smrg if (*cp++ != *np++) 6743f32c10Smrg break; 6843f32c10Smrg if (i == 0 && *cp++ == '=') { 6943f32c10Smrg *offset = p - environ; 7043f32c10Smrg return cp; 7143f32c10Smrg } 7243f32c10Smrg } 7343f32c10Smrg return NULL; 7443f32c10Smrg} 7543f32c10Smrg 7643f32c10Smrg/* 7743f32c10Smrg * setenv -- 7843f32c10Smrg * Set the value of the environmental variable "name" to be 7943f32c10Smrg * "value". If overwrite is set, replace any current value. 8043f32c10Smrg */ 8143f32c10Smrg 8243f32c10Smrgint 8343f32c10Smrgsetenv(const char *name, const char *value, int overwrite) 8443f32c10Smrg{ 8543f32c10Smrg static char **alloced; /* if allocated space before */ 8643f32c10Smrg char *c; 8743f32c10Smrg int l_value, offset; 8843f32c10Smrg 8943f32c10Smrg if (*value == '=') /* no '=' in value */ 9043f32c10Smrg ++value; 9143f32c10Smrg l_value = strlen(value); 9243f32c10Smrg if ((c = findenv(name, &offset))) { /* find if already exists */ 9343f32c10Smrg if (!overwrite) 9443f32c10Smrg return 0; 9543f32c10Smrg if (strlen(c) >= l_value) { /* old larger; copy over */ 9643f32c10Smrg while ((*c++ = *value++)) 9743f32c10Smrg ; 9843f32c10Smrg return 0; 9943f32c10Smrg } 10043f32c10Smrg } else { /* create new slot */ 10143f32c10Smrg int cnt; 10243f32c10Smrg char **p; 10343f32c10Smrg 10443f32c10Smrg for (p = environ, cnt = 0; *p; ++p, ++cnt) 10543f32c10Smrg ; 10643f32c10Smrg if (alloced == environ) { /* just increase size */ 10743f32c10Smrg p = (char **)realloc((char *)environ, 10843f32c10Smrg sizeof(char *) * (cnt + 2)); 10943f32c10Smrg if (!p) 11043f32c10Smrg return -1; 11143f32c10Smrg alloced = environ = p; 11243f32c10Smrg } else { /* get new space */ 11343f32c10Smrg /* copy old entries into it */ 11443f32c10Smrg p = malloc(sizeof(char *) * (cnt + 2)); 11543f32c10Smrg if (!p) 11643f32c10Smrg return -1; 11743f32c10Smrg memcpy(p, environ, cnt * sizeof(char *)); 11843f32c10Smrg alloced = environ = p; 11943f32c10Smrg } 12043f32c10Smrg environ[cnt + 1] = NULL; 12143f32c10Smrg offset = cnt; 12243f32c10Smrg } 12343f32c10Smrg for (c = (char *)name; *c && *c != '='; ++c) /* no '=' in name */ 12443f32c10Smrg ; 12543f32c10Smrg if (!(environ[offset] = /* name + '=' + value */ 12643f32c10Smrg malloc((int)(c - name) + l_value + 2))) 12743f32c10Smrg return -1; 12843f32c10Smrg for (c = environ[offset]; (*c = *name++) && *c != '='; ++c) 12943f32c10Smrg ; 13043f32c10Smrg for (*c++ = '='; (*c++ = *value++); ) 13143f32c10Smrg ; 13243f32c10Smrg return 0; 13343f32c10Smrg} 13443f32c10Smrg 13543f32c10Smrg/* 13643f32c10Smrg * unsetenv(name) -- 13743f32c10Smrg * Delete environmental variable "name". 13843f32c10Smrg */ 13943f32c10Smrg 14043f32c10Smrgvoid 14143f32c10Smrgunsetenv(const char *name) 14243f32c10Smrg{ 14343f32c10Smrg char **p; 14443f32c10Smrg int offset; 14543f32c10Smrg 14643f32c10Smrg while (findenv(name, &offset)) /* if set multiple times */ 14743f32c10Smrg for (p = &environ[offset];; ++p) 14843f32c10Smrg if (!(*p = *(p + 1))) 14943f32c10Smrg break; 15043f32c10Smrg} 15143f32c10Smrg 152