Commit of the code which was suggested by Georg as a fix for:
[cake.git] / rom / dos / setvar.c
blobdf465fa0637944baf69c2e2783412bcb1f899b2c
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include "dos_intern.h"
10 #include <exec/memory.h>
11 #include <dos/dos.h>
12 #include <dos/dosextens.h>
13 #include <proto/exec.h>
14 #include <proto/utility.h>
15 #include <exec/lists.h>
16 #include <string.h>
18 /*****************************************************************************
20 NAME */
21 #include <dos/var.h>
22 #include <proto/dos.h>
24 AROS_LH4(BOOL, SetVar,
26 /* SYNOPSIS */
27 AROS_LHA(CONST_STRPTR, name, D1),
28 AROS_LHA(CONST_STRPTR, buffer, D2),
29 AROS_LHA(LONG , size, D3),
30 AROS_LHA(LONG , flags, D4),
32 /* LOCATION */
33 struct DosLibrary *, DOSBase, 150, Dos)
35 /* FUNCTION
36 This function will set a local of environmental variable. Although
37 it is recommended that you only use ASCII strings within variables,
38 this is not actually required.
40 Variable names are not case sensitive.
42 SetVar() for an already existing variable changes the variable's
43 value to "buffer".
45 INPUTS
46 name - The name of the variable to set.
47 buffer - The actual data of the variable.
48 size - The size of the data in the buffer.
49 flags - Combination of the type of variable to set (lower
50 8 bits of the value), and various flags which control
51 this function. Flags defined are:
53 GVF_LOCAL_ONLY - set a local variable only,
54 GVF_GLOBAL_ONLY - set a global environmental
55 variable only.
56 GVF_SAVE_VAR - If GVF_GLOBAL_ONLY is set, then
57 this flag will cause SetVar() to
58 save the variable to ENVARC: as well
59 as to ENV:.
60 GVF_BINARY_VAR and GVF_DONT_NULL_TERM are stored in
61 the lv_Flags field for local variables, but not
62 used otherwise by SetVar().
64 Note the default is to set a local environmental
65 variable.
67 The following variable types are defined:
68 LV_VAR - local environment variable
69 LV_ALIAS - shell alias
70 LVF_IGNORE - internal shell use
72 LV_VAR and LV_ALIAS should be treated as
73 "exclusive or".
76 RESULT
77 Zero if this function failed, non-zero otherwise.
79 NOTES
80 It is possible to have two variables with the same name as
81 long as they have different types.
83 EXAMPLE
85 BUGS
86 Only type LV_VAR can be made global.
88 If you set GVF_SAVE_VAR, and this function returns failure, the
89 variable may have still been set in ENV:.
91 SEE ALSO
92 DeleteVar(), FindVar(), GetVar(),
94 INTERNALS
95 See FindVar() for a description of the inner workings of local
96 variables.
98 *****************************************************************************/
100 AROS_LIBFUNC_INIT
102 /* valid input? */
103 if(name && buffer && size)
105 /* Local variable is default. */
106 if((flags & GVF_GLOBAL_ONLY) == 0)
108 ULONG nameLen = strlen(name);
109 struct LocalVar *lv;
111 /* does a Variable with that name already exist? */
112 if (NULL != (lv = FindVar(name, flags)))
114 /* delete old value of that existing variable */
115 FreeMem(lv->lv_Value,lv->lv_Len);
117 else
120 ** create a LocalVar-structure and insert it into the list
122 if (NULL != (lv = AllocVec(sizeof(struct LocalVar) + nameLen + 1,
123 MEMF_CLEAR|MEMF_PUBLIC) ) )
125 struct Process *pr = (struct Process *)FindTask(NULL);
126 struct LocalVar *n = (struct LocalVar *)pr->pr_LocalVars.mlh_Head;
128 /* init the newly created structure */
130 lv->lv_Node.ln_Type = flags; /* ln_Type is UBYTE! */
131 lv->lv_Node.ln_Name = (UBYTE *)lv + sizeof(struct LocalVar);
132 CopyMem(name, lv->lv_Node.ln_Name, nameLen);
133 lv->lv_Flags = flags & (GVF_BINARY_VAR|GVF_DONT_NULL_TERM);
136 ** First let's see whether we have to add it at the head
137 ** of the list as the list is still empty OR
138 ** the very first element is already greater than the one
139 ** we want to insert
142 if (n == (struct LocalVar *)&(pr->pr_LocalVars.mlh_Tail) ||
143 Stricmp(name, n->lv_Node.ln_Name) < 0)
145 AddHead((struct List *)&pr->pr_LocalVars,
146 (struct Node *)lv);
148 else
151 ** Now we can be sure that we will have to insert
152 ** somewhere behind the first element in the list
154 ForeachNode(&pr->pr_LocalVars, n)
156 if (Stricmp(name, n->lv_Node.ln_Name) < 0)
158 break;
162 if (NULL != n->lv_Node.ln_Succ)
164 Insert((struct List *)&pr->pr_LocalVars ,
165 (struct Node *) lv ,
166 (struct Node *) n->lv_Node.ln_Pred);
168 else
170 AddTail((struct List *)&pr->pr_LocalVars,
171 (struct Node *) lv);
177 /* -1 as size means: buffer contains a null-terminated string*/
178 if (-1 == size)
180 /* Do NOT add 1 byte to account for the NUL char, AmigaOS(R) doesn't
181 do it that way. */
182 lv->lv_Len = strlen(buffer);
184 else
186 lv->lv_Len = size;
189 /* now get some memory for the value*/
190 lv->lv_Value = AllocMem(lv->lv_Len, MEMF_PUBLIC);
192 if (lv->lv_Value)
194 CopyMem(buffer, lv->lv_Value, lv->lv_Len);
196 if (flags & GVF_LOCAL_ONLY)
197 return DOSTRUE;
198 } /* memory for actual value */
199 } /* set a local variable */
201 /* Ok, try and set a global variable. */
202 if ((flags & GVF_LOCAL_ONLY) == 0)
204 BPTR file;
205 /* as a standard: look for the file in ENV: if no path is
206 given in the variable */
207 UBYTE nameBuffer[384]= "ENV:";
209 AddPart(nameBuffer, name, 384);
211 /* Just try and open the file */
212 file = Open(nameBuffer, MODE_NEWFILE);
214 if (file != NULL)
216 /* Write the data to the file */
217 /* size = -1 means that the value is a null-terminated
218 string */
219 if (-1 == size)
221 Write(file, buffer, strlen(buffer));
223 else
225 Write(file, buffer, size);
228 Close(file);
230 else
232 return DOSFALSE;
235 /* Let's see whether we're supposed to make a copy of this to
236 * envarc also...
238 if (0 != (flags & GVF_SAVE_VAR))
240 CopyMem("ENVARC:", nameBuffer, 8);
241 AddPart(nameBuffer, name, 384);
243 file = Open(nameBuffer, MODE_NEWFILE);
245 if (file != NULL)
247 /* Write the data to the file */
248 /* size = -1 means that the value is a null-terminated
249 string */
250 if (-1 == size)
252 Write(file, buffer, strlen(buffer));
254 else
256 Write(file, buffer, size);
259 Close(file);
263 /* We created both, bye bye */
264 return DOSTRUE;
265 } /* try a global variable */
266 } /* input was valid */
268 return DOSFALSE;
270 AROS_LIBFUNC_EXIT
271 } /* SetVar */