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