172445Sassar/* 2178825Sdfr * Copyright (c) 2000, 2005 Kungliga Tekniska H�gskolan 372445Sassar * (Royal Institute of Technology, Stockholm, Sweden). 472445Sassar * All rights reserved. 572445Sassar * 672445Sassar * Redistribution and use in source and binary forms, with or without 772445Sassar * modification, are permitted provided that the following conditions 872445Sassar * are met: 972445Sassar * 1072445Sassar * 1. Redistributions of source code must retain the above copyright 1172445Sassar * notice, this list of conditions and the following disclaimer. 1272445Sassar * 1372445Sassar * 2. Redistributions in binary form must reproduce the above copyright 1472445Sassar * notice, this list of conditions and the following disclaimer in the 1572445Sassar * documentation and/or other materials provided with the distribution. 1672445Sassar * 1772445Sassar * 3. Neither the name of the Institute nor the names of its contributors 1872445Sassar * may be used to endorse or promote products derived from this software 1972445Sassar * without specific prior written permission. 2072445Sassar * 2172445Sassar * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2272445Sassar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2372445Sassar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2472445Sassar * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2572445Sassar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2672445Sassar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2772445Sassar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2872445Sassar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2972445Sassar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3072445Sassar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3172445Sassar * SUCH DAMAGE. 3272445Sassar */ 3372445Sassar 3472445Sassar 3572445Sassar#ifdef HAVE_CONFIG_H 3672445Sassar#include <config.h> 37178825SdfrRCSID("$Id: environment.c 20866 2007-06-03 21:00:29Z lha $"); 3872445Sassar#endif 3972445Sassar 4072445Sassar#include <stdio.h> 4172445Sassar#include <string.h> 42178825Sdfr#include <ctype.h> 4372445Sassar#include "roken.h" 4472445Sassar 45178825Sdfr/* find assignment in env list; len is length of variable including 46178825Sdfr * equal 47178825Sdfr */ 48178825Sdfr 49178825Sdfrstatic int 50178825Sdfrfind_var(char **env, char *assignment, size_t len) 51178825Sdfr{ 52178825Sdfr int i; 53178825Sdfr for(i = 0; env != NULL && env[i] != NULL; i++) 54178825Sdfr if(strncmp(env[i], assignment, len) == 0) 55178825Sdfr return i; 56178825Sdfr return -1; 57178825Sdfr} 58178825Sdfr 5972445Sassar/* 60178825Sdfr * return count of environment assignments from open file F in 61178825Sdfr * assigned and list of malloced strings in env, return 0 or errno 62178825Sdfr * number 6372445Sassar */ 6472445Sassar 65178825Sdfrstatic int 66178825Sdfrrk_read_env_file(FILE *F, char ***env, int *assigned) 6772445Sassar{ 68178825Sdfr int idx = 0; 69178825Sdfr int i; 7072445Sassar char **l; 7172445Sassar char buf[BUFSIZ], *p, *r; 72178825Sdfr char **tmp; 73178825Sdfr int ret = 0; 7472445Sassar 75178825Sdfr *assigned = 0; 7672445Sassar 77178825Sdfr for(idx = 0; *env != NULL && (*env)[idx] != NULL; idx++); 7872445Sassar l = *env; 79178825Sdfr 8072445Sassar /* This is somewhat more relaxed on what it accepts then 8172445Sassar * Wietses sysv_environ from K4 was... 8272445Sassar */ 8372445Sassar while (fgets(buf, BUFSIZ, F) != NULL) { 84178825Sdfr buf[strcspn(buf, "#\n")] = '\0'; 8572445Sassar 86178825Sdfr for(p = buf; isspace((unsigned char)*p); p++); 8772445Sassar if (*p == '\0') 8872445Sassar continue; 8972445Sassar 90178825Sdfr /* Here one should check that it's a 'valid' env string... */ 9172445Sassar r = strchr(p, '='); 9272445Sassar if (r == NULL) 9372445Sassar continue; 9472445Sassar 95178825Sdfr if((i = find_var(l, p, r - p + 1)) >= 0) { 96178825Sdfr char *val = strdup(p); 97178825Sdfr if(val == NULL) { 98178825Sdfr ret = ENOMEM; 99178825Sdfr break; 100178825Sdfr } 101178825Sdfr free(l[i]); 102178825Sdfr l[i] = val; 103178825Sdfr (*assigned)++; 104178825Sdfr continue; 105178825Sdfr } 106178825Sdfr 107178825Sdfr tmp = realloc(l, (idx+2) * sizeof (char *)); 108178825Sdfr if(tmp == NULL) { 109178825Sdfr ret = ENOMEM; 110178825Sdfr break; 111178825Sdfr } 112178825Sdfr 113178825Sdfr l = tmp; 114178825Sdfr l[idx] = strdup(p); 115178825Sdfr if(l[idx] == NULL) { 116178825Sdfr ret = ENOMEM; 117178825Sdfr break; 118178825Sdfr } 119178825Sdfr l[++idx] = NULL; 120178825Sdfr (*assigned)++; 12172445Sassar } 122178825Sdfr if(ferror(F)) 123178825Sdfr ret = errno; 12472445Sassar *env = l; 125178825Sdfr return ret; 12672445Sassar} 127178825Sdfr 128178825Sdfr/* 129178825Sdfr * return count of environment assignments from file and 130178825Sdfr * list of malloced strings in `env' 131178825Sdfr */ 132178825Sdfr 133178825Sdfrint ROKEN_LIB_FUNCTION 134178825Sdfrread_environment(const char *file, char ***env) 135178825Sdfr{ 136178825Sdfr int assigned; 137178825Sdfr FILE *F; 138178825Sdfr 139178825Sdfr if ((F = fopen(file, "r")) == NULL) 140178825Sdfr return 0; 141178825Sdfr 142178825Sdfr rk_read_env_file(F, env, &assigned); 143178825Sdfr fclose(F); 144178825Sdfr return assigned; 145178825Sdfr} 146178825Sdfr 147178825Sdfrvoid ROKEN_LIB_FUNCTION 148178825Sdfrfree_environment(char **env) 149178825Sdfr{ 150178825Sdfr int i; 151178825Sdfr if (env == NULL) 152178825Sdfr return; 153178825Sdfr for (i = 0; env[i]; i++) 154178825Sdfr free(env[i]); 155178825Sdfr free(env); 156178825Sdfr} 157