2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
5 Internal functions for environment variables handling.
8 #include "__arosc_privdata.h"
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/utility.h>
19 #if AROS_AMIGAOS_COMPLIANCE && (AROS_AMIGAOS_COMPLIANCE >= 30)
20 /* ScanVars is a Morphos addition in dos.library v50, so we
21 * have this stub here for arosc.library compatability with
22 * dos.library v30..v39.
24 static LONG
v30_ScanVars(struct Hook
*hook
, ULONG flags
, APTR userdata
)
26 /* We scan through the process->pr_LocalVars list */
29 struct ScanVarsMsg msg
;
33 UtilityBase
= OpenLibrary("utility.library", 0);
34 if (UtilityBase
== NULL
)
37 msg
.sv_SVMSize
= sizeof(struct ScanVarsMsg
);
39 pr
= (struct Process
*)FindTask(NULL
);
41 /* We know that the callers of this routine
42 * will be asking for GVF_LOCAL_ONLY
44 var
= (struct LocalVar
*)pr
->pr_LocalVars
.mlh_Head
;
46 ForeachNode(&pr
->pr_LocalVars
, var
)
48 if (var
->lv_Node
.ln_Type
== LV_VAR
)
50 msg
.sv_Name
= var
->lv_Node
.ln_Name
;
51 msg
.sv_Var
= var
->lv_Value
;
52 msg
.sv_VarLen
= var
->lv_Len
;
54 res
= CallHookPkt(hook
, userdata
, &msg
);
60 CloseLibrary(UtilityBase
);
64 #define ScanVars(a,b,c) v30_ScanVars(a,b,c)
67 static __env_item
*__env_newvar(const char *name
, int valuesize
)
71 item
= malloc(sizeof(__env_item
));
74 item
->name
= strdup(name
);
75 if (!item
->name
) goto err2
;
77 item
->value
= malloc(valuesize
);
78 if (!item
->value
) goto err3
;
92 static __env_item
**internal_findvar(register const char *name
)
94 struct aroscbase
*aroscbase
= __aros_getbase_aroscbase();
99 curr
= &aroscbase
->acb_env_list
;
100 *curr
&& strcmp((*curr
)->name
, name
);
101 curr
= &((*curr
)->next
)
108 Allocates space for a variable with name 'name' returning a pointer to it.
109 If a variable with this name already exists then returns a pointer to that
112 Returns NULL on error.
114 __env_item
*__env_getvar(const char *name
, int valuesize
)
116 register __env_item
**curr
;
118 curr
= internal_findvar(name
);
122 if (strlen((*curr
)->value
) < valuesize
)
124 free((*curr
)->value
);
125 (*curr
)->value
= malloc(valuesize
);
129 __env_item
*tmp
= (*curr
)->next
;
138 *curr
= __env_newvar(name
, valuesize
);
144 void __env_delvar(const char *name
)
146 register __env_item
**curr
;
148 curr
= internal_findvar(name
);
152 register __env_item
*tmp
= *curr
;
154 *curr
= (*curr
)->next
;
169 /* Hook function counting the number of variables and computing the buffer size
170 needed for name=value character buffer. */
171 LONG
get_var_len(struct Hook
*hook
, APTR userdata
, struct ScanVarsMsg
*message
)
173 struct EnvData
*data
= (struct EnvData
*) userdata
;
176 (ptrdiff_t) strlen((char*)message
->sv_Name
) +
177 message
->sv_VarLen
+ 2;
181 /* Hook function storing name=value strings in buffer */
182 LONG
get_var(struct Hook
*hook
, APTR userdata
, struct ScanVarsMsg
*message
)
184 struct EnvData
*data
= userdata
;
185 data
->varbufptr
[0] = '\0';
186 strcat(data
->varbufptr
, (char*) message
->sv_Name
);
187 strcat(data
->varbufptr
, "=");
188 strncat(data
->varbufptr
, (char*) message
->sv_Var
, message
->sv_VarLen
);
189 data
->varbufptr
= data
->varbufptr
+ strlen(data
->varbufptr
) + 1;
193 /* Function storing name=value strings in given environ buffer. When buffer is
194 null, it returns minimal necessary size of the buffer needed to store all
195 name=value strings. */
196 int __env_get_environ(char **environ
, int size
)
206 memset(&hook
, 0, sizeof(struct Hook
));
207 hook
.h_Entry
= (HOOKFUNC
) get_var_len
;
208 ScanVars(&hook
, GVF_LOCAL_ONLY
, &u
);
211 return sizeof(char*) * (u
.envcount
+ 1) + u
.varbufsize
;
212 else if(size
< sizeof(char*) *(u
.envcount
+ 1) + u
.varbufsize
)
215 /* store name=value strings after table of pointers */
216 varbuf
= (char*) (environ
+ (u
.envcount
+ 1));
218 /* time to fill in the buffers */
219 u
.varbufptr
= varbuf
;
220 u
.varbufptr
[0] = '\0';
221 hook
.h_Entry
= (HOOKFUNC
) get_var
;
222 ScanVars(&hook
, GVF_LOCAL_ONLY
, &u
);
224 for(i
= 0; i
< u
.envcount
; i
++)
227 varbuf
= strchr(varbuf
, '\0') + 1;
229 environ
[u
.envcount
] = NULL
;