emul-handler: fh_Arg1 should be the only element of struct FileHandle touched during...
[AROS.git] / rom / dos / setvar.c
blob01ea433854f245b7b2316c1dbdcd9d5a428d57cb
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
8 #include <aros/debug.h>
10 #include "dos_intern.h"
11 #include <exec/memory.h>
12 #include <dos/dos.h>
13 #include <dos/dosextens.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <exec/lists.h>
17 #include <string.h>
19 /*****************************************************************************
21 NAME */
22 #include <dos/var.h>
23 #include <proto/dos.h>
25 AROS_LH4(BOOL, SetVar,
27 /* SYNOPSIS */
28 AROS_LHA(CONST_STRPTR, name, D1),
29 AROS_LHA(CONST_STRPTR, buffer, D2),
30 AROS_LHA(LONG , size, D3),
31 AROS_LHA(LONG , flags, D4),
33 /* LOCATION */
34 struct DosLibrary *, DOSBase, 150, Dos)
36 /* FUNCTION
37 This function will set a local or environmental variable. Although
38 it is recommended that you only use ASCII strings within variables,
39 this is not actually required.
41 Variable names are not case sensitive.
43 SetVar() for an already existing variable changes the variable's
44 value to "buffer".
46 INPUTS
47 name - The name of the variable to set.
48 buffer - The actual data of the variable.
49 size - The size of the data in the buffer.
50 flags - Combination of the type of variable to set (lower
51 8 bits of the value), and various flags which control
52 this function. Flags defined are:
54 GVF_LOCAL_ONLY - set a local variable only,
55 GVF_GLOBAL_ONLY - set a global environmental
56 variable only.
57 GVF_SAVE_VAR - If GVF_GLOBAL_ONLY is set, then
58 this flag will cause SetVar() to
59 save the variable to ENVARC: as well
60 as to ENV:.
61 GVF_BINARY_VAR and GVF_DONT_NULL_TERM are stored in
62 the lv_Flags field for local variables, but not
63 used otherwise by SetVar().
65 Note the default is to set a local environmental
66 variable.
68 The following variable types are defined:
69 LV_VAR - local environment variable
70 LV_ALIAS - shell alias
71 LVF_IGNORE - internal shell use
73 LV_VAR and LV_ALIAS should be treated as
74 "exclusive or".
77 RESULT
78 Zero if this function failed, non-zero otherwise.
80 NOTES
81 It is possible to have two variables with the same name as
82 long as they have different types.
84 EXAMPLE
86 BUGS
87 Only type LV_VAR can be made global.
89 If you set GVF_SAVE_VAR, and this function returns failure, the
90 variable may have still been set in ENV:.
92 SEE ALSO
93 DeleteVar(), FindVar(), GetVar(),
95 INTERNALS
96 See FindVar() for a description of the inner workings of local
97 variables.
99 *****************************************************************************/
101 AROS_LIBFUNC_INIT
103 /* valid input? */
104 if(name && buffer)
106 /* Local variable is default. */
107 if((flags & GVF_GLOBAL_ONLY) == 0)
109 ULONG nameLen = strlen(name);
110 struct LocalVar *lv;
112 /* does a Variable with that name already exist? */
113 if (NULL != (lv = FindVar(name, flags)))
115 /* delete old value of that existing variable */
116 FreeMem(lv->lv_Value,lv->lv_Len);
118 else
121 ** create a LocalVar-structure and insert it into the list
123 if (NULL != (lv = AllocVec(sizeof(struct LocalVar) + nameLen + 1,
124 MEMF_CLEAR|MEMF_PUBLIC) ) )
126 struct Process *pr = (struct Process *)FindTask(NULL);
127 struct LocalVar *n;
129 ASSERT_VALID_PROCESS(pr);
130 n = (struct LocalVar *)pr->pr_LocalVars.mlh_Head;
132 /* init the newly created structure */
134 lv->lv_Node.ln_Type = flags; /* ln_Type is UBYTE! */
135 lv->lv_Node.ln_Name = (UBYTE *)lv + sizeof(struct LocalVar);
136 CopyMem(name, lv->lv_Node.ln_Name, nameLen);
137 lv->lv_Flags = flags & (GVF_BINARY_VAR|GVF_DONT_NULL_TERM);
140 ** First let's see whether we have to add it at the head
141 ** of the list as the list is still empty OR
142 ** the very first element is already greater than the one
143 ** we want to insert
146 if (n == (struct LocalVar *)&(pr->pr_LocalVars.mlh_Tail) ||
147 Stricmp(name, n->lv_Node.ln_Name) < 0)
149 AddHead((struct List *)&pr->pr_LocalVars,
150 (struct Node *)lv);
152 else
155 ** Now we can be sure that we will have to insert
156 ** somewhere behind the first element in the list
158 ForeachNode(&pr->pr_LocalVars, n)
160 if (Stricmp(name, n->lv_Node.ln_Name) < 0)
162 break;
166 if (NULL != n->lv_Node.ln_Succ)
168 Insert((struct List *)&pr->pr_LocalVars ,
169 (struct Node *) lv ,
170 (struct Node *) n->lv_Node.ln_Pred);
172 else
174 AddTail((struct List *)&pr->pr_LocalVars,
175 (struct Node *) lv);
181 /* -1 as size means: buffer contains a null-terminated string */
182 if (-1 == size)
184 /* Do NOT add 1 byte to account for the NUL char, AmigaOS(R) doesn't
185 do it that way. */
186 lv->lv_Len = strlen(buffer);
188 else
190 lv->lv_Len = size;
193 /* now get some memory for the value */
194 lv->lv_Value = AllocMem(lv->lv_Len, MEMF_PUBLIC);
196 CopyMem(buffer, lv->lv_Value, lv->lv_Len);
198 if (flags & GVF_LOCAL_ONLY)
199 return DOSTRUE;
200 } /* set a local variable */
202 /* Ok, try and set a global variable. */
203 if ((flags & GVF_LOCAL_ONLY) == 0)
205 BPTR file;
206 /* as a standard: look for the file in ENV: if no path is
207 given in the variable */
208 UBYTE nameBuffer[384]= "ENV:";
210 AddPart(nameBuffer, name, 384);
212 /* Just try and open the file */
213 file = Open(nameBuffer, MODE_NEWFILE);
215 if (file != BNULL)
217 /* Write the data to the file */
218 /* size = -1 means that the value is a null-terminated
219 string */
220 if (-1 == size)
222 Write(file, buffer, strlen(buffer));
224 else
226 Write(file, buffer, size);
229 Close(file);
231 else
233 return DOSFALSE;
236 /* Let's see whether we're supposed to make a copy of this to
237 * envarc also...
239 if (0 != (flags & GVF_SAVE_VAR))
241 CopyMem("ENVARC:", nameBuffer, 8);
242 AddPart(nameBuffer, name, 384);
244 file = Open(nameBuffer, MODE_NEWFILE);
246 if (file != BNULL)
248 /* Write the data to the file */
249 /* size = -1 means that the value is a null-terminated
250 string */
251 if (-1 == size)
253 Write(file, buffer, strlen(buffer));
255 else
257 Write(file, buffer, size);
260 Close(file);
264 /* We created both, bye bye */
265 return DOSTRUE;
266 } /* try a global variable */
267 } /* input was valid */
269 return DOSFALSE;
271 AROS_LIBFUNC_EXIT
272 } /* SetVar */