Small cleanup of extensions code
[AROS.git] / compiler / clib / __env.c
blobfce93d6b7dc7e172f6dd3bf335ada83e568bd25f
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 Internal functions for environment variables handling.
6 */
8 #include "__arosc_privdata.h"
10 #include <stdlib.h>
11 #include <strings.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/utility.h>
15 #include <dos/var.h>
17 #include "__env.h"
19 static __env_item *__env_newvar(const char *name, int valuesize)
21 __env_item *item;
23 item = malloc(sizeof(__env_item));
24 if (!item) goto err1;
26 item->name = strdup(name);
27 if (!item->name) goto err2;
29 item->value = malloc(valuesize);
30 if (!item->value) goto err3;
32 item->next = NULL;
34 return item;
36 err3:
37 free(item->name);
38 err2:
39 free(item);
40 err1:
41 return NULL;
44 static __env_item **internal_findvar(register const char *name)
47 __env_item **curr;
49 for (
50 curr = &__env_list;
51 *curr && strcmp((*curr)->name, name);
52 curr = &((*curr)->next)
55 return curr;
59 Allocates space for a variable with name 'name' returning a pointer to it.
60 If a variable with this name already exists then returns a pointer to that
61 variable.
63 Returns NULL on error.
65 __env_item *__env_getvar(const char *name, int valuesize)
67 register __env_item **curr;
69 curr = internal_findvar(name);
71 if (*curr)
73 if (strlen((*curr)->value) < valuesize)
75 free((*curr)->value);
76 (*curr)->value = malloc(valuesize);
78 if (!(*curr)->value)
80 __env_item *tmp = (*curr)->next;
82 free(*curr);
83 *curr = tmp;
87 else
89 *curr = __env_newvar(name, valuesize);
92 return *curr;
95 void __env_delvar(const char *name)
97 register __env_item **curr;
99 curr = internal_findvar(name);
101 if (*curr)
103 register __env_item *tmp = *curr;
105 *curr = (*curr)->next;
107 free(tmp->name);
108 free(tmp->value);
109 free(tmp);
113 struct EnvData
115 int envcount;
116 int varbufsize;
117 char * varbufptr;
120 /* Hook function counting the number of variables and computing the buffer size
121 needed for name=value character buffer. */
122 LONG get_var_len(struct Hook *hook, APTR userdata, struct ScanVarsMsg *message)
124 struct EnvData *data = (struct EnvData *) userdata;
125 data->envcount++;
126 data->varbufsize +=
127 (ptrdiff_t) strlen((char*)message->sv_Name) +
128 message->sv_VarLen + 2;
129 return 0;
132 /* Hook function storing name=value strings in buffer */
133 LONG get_var(struct Hook *hook, APTR userdata, struct ScanVarsMsg *message)
135 struct EnvData *data = userdata;
136 data->varbufptr[0] = '\0';
137 strcat(data->varbufptr, (char*) message->sv_Name);
138 strcat(data->varbufptr, "=");
139 strncat(data->varbufptr, (char*) message->sv_Var, message->sv_VarLen);
140 data->varbufptr = data->varbufptr + strlen(data->varbufptr) + 1;
141 return 0;
144 /* Function storing name=value strings in given environ buffer. When buffer is
145 null, it returns minimal necessary size of the buffer needed to store all
146 name=value strings. */
147 int __env_get_environ(char **environ, int size)
149 int i;
150 struct Hook hook;
151 struct EnvData u;
152 char *varbuf;
154 u.envcount = 0;
155 u.varbufsize = 0;
157 memset(&hook, 0, sizeof(struct Hook));
158 hook.h_Entry = (HOOKFUNC) get_var_len;
159 ScanVars(&hook, GVF_LOCAL_ONLY, &u);
161 if(environ == NULL)
162 return sizeof(char*) * (u.envcount + 1) + u.varbufsize;
163 else if(size < sizeof(char*) *(u.envcount + 1) + u.varbufsize)
164 return -1;
166 /* store name=value strings after table of pointers */
167 varbuf = (char*) (environ + (u.envcount + 1));
169 /* time to fill in the buffers */
170 u.varbufptr = varbuf;
171 u.varbufptr[0] = '\0';
172 hook.h_Entry = (HOOKFUNC) get_var;
173 ScanVars(&hook, GVF_LOCAL_ONLY, &u);
175 for(i = 0; i < u.envcount; i++)
177 environ[i] = varbuf;
178 varbuf = strchr(varbuf, '\0') + 1;
180 environ[u.envcount] = NULL;
182 return 0;