172445Sassar/*
2233294Sstas * Copyright (c) 2000, 2005 Kungliga Tekniska H��gskolan
372445Sassar * (Royal Institute of Technology, Stockholm, Sweden).
472445Sassar * All rights reserved.
5233294Sstas *
672445Sassar * Redistribution and use in source and binary forms, with or without
772445Sassar * modification, are permitted provided that the following conditions
872445Sassar * are met:
9233294Sstas *
1072445Sassar * 1. Redistributions of source code must retain the above copyright
1172445Sassar *    notice, this list of conditions and the following disclaimer.
12233294Sstas *
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.
16233294Sstas *
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.
20233294Sstas *
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#include <config.h>
3672445Sassar
3772445Sassar#include <stdio.h>
3872445Sassar#include <string.h>
39178825Sdfr#include <ctype.h>
4072445Sassar#include "roken.h"
4172445Sassar
42178825Sdfr/* find assignment in env list; len is length of variable including
43233294Sstas * equal
44178825Sdfr */
45178825Sdfr
46178825Sdfrstatic int
47178825Sdfrfind_var(char **env, char *assignment, size_t len)
48178825Sdfr{
49178825Sdfr    int i;
50178825Sdfr    for(i = 0; env != NULL && env[i] != NULL; i++)
51178825Sdfr	if(strncmp(env[i], assignment, len) == 0)
52178825Sdfr	    return i;
53178825Sdfr    return -1;
54178825Sdfr}
55178825Sdfr
5672445Sassar/*
57178825Sdfr * return count of environment assignments from open file F in
58178825Sdfr * assigned and list of malloced strings in env, return 0 or errno
59178825Sdfr * number
6072445Sassar */
6172445Sassar
62178825Sdfrstatic int
63233294Sstasread_env_file(FILE *F, char ***env, int *assigned)
6472445Sassar{
65178825Sdfr    int idx = 0;
66178825Sdfr    int i;
6772445Sassar    char **l;
6872445Sassar    char buf[BUFSIZ], *p, *r;
69178825Sdfr    char **tmp;
70178825Sdfr    int ret = 0;
7172445Sassar
72178825Sdfr    *assigned = 0;
7372445Sassar
74178825Sdfr    for(idx = 0; *env != NULL && (*env)[idx] != NULL; idx++);
7572445Sassar    l = *env;
76178825Sdfr
7772445Sassar    /* This is somewhat more relaxed on what it accepts then
7872445Sassar     * Wietses sysv_environ from K4 was...
7972445Sassar     */
8072445Sassar    while (fgets(buf, BUFSIZ, F) != NULL) {
81178825Sdfr	buf[strcspn(buf, "#\n")] = '\0';
8272445Sassar
83178825Sdfr	for(p = buf; isspace((unsigned char)*p); p++);
8472445Sassar	if (*p == '\0')
8572445Sassar	    continue;
8672445Sassar
87178825Sdfr	/* Here one should check that it's a 'valid' env string... */
8872445Sassar	r = strchr(p, '=');
8972445Sassar	if (r == NULL)
9072445Sassar	    continue;
9172445Sassar
92178825Sdfr	if((i = find_var(l, p, r - p + 1)) >= 0) {
93178825Sdfr	    char *val = strdup(p);
94178825Sdfr	    if(val == NULL) {
95178825Sdfr		ret = ENOMEM;
96178825Sdfr		break;
97178825Sdfr	    }
98178825Sdfr	    free(l[i]);
99178825Sdfr	    l[i] = val;
100178825Sdfr	    (*assigned)++;
101178825Sdfr	    continue;
102178825Sdfr	}
103178825Sdfr
104178825Sdfr	tmp = realloc(l, (idx+2) * sizeof (char *));
105178825Sdfr	if(tmp == NULL) {
106178825Sdfr	    ret = ENOMEM;
107178825Sdfr	    break;
108178825Sdfr	}
109178825Sdfr
110178825Sdfr	l = tmp;
111178825Sdfr	l[idx] = strdup(p);
112178825Sdfr	if(l[idx] == NULL) {
113178825Sdfr	    ret = ENOMEM;
114178825Sdfr	    break;
115178825Sdfr	}
116178825Sdfr	l[++idx] = NULL;
117178825Sdfr	(*assigned)++;
11872445Sassar    }
119178825Sdfr    if(ferror(F))
120178825Sdfr	ret = errno;
12172445Sassar    *env = l;
122178825Sdfr    return ret;
12372445Sassar}
124178825Sdfr
125178825Sdfr/*
126233294Sstas * return count of environment assignments from file and
127178825Sdfr * list of malloced strings in `env'
128178825Sdfr */
129178825Sdfr
130233294SstasROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
131178825Sdfrread_environment(const char *file, char ***env)
132178825Sdfr{
133178825Sdfr    int assigned;
134178825Sdfr    FILE *F;
135178825Sdfr
136178825Sdfr    if ((F = fopen(file, "r")) == NULL)
137178825Sdfr	return 0;
138178825Sdfr
139233294Sstas    read_env_file(F, env, &assigned);
140178825Sdfr    fclose(F);
141178825Sdfr    return assigned;
142178825Sdfr}
143178825Sdfr
144233294SstasROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
145178825Sdfrfree_environment(char **env)
146178825Sdfr{
147178825Sdfr    int i;
148178825Sdfr    if (env == NULL)
149178825Sdfr	return;
150178825Sdfr    for (i = 0; env[i]; i++)
151178825Sdfr	free(env[i]);
152178825Sdfr    free(env);
153178825Sdfr}
154