2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
10 #include "dos_intern.h"
11 #include <exec/memory.h>
13 #include <dos/dosextens.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <exec/lists.h>
19 /*****************************************************************************
23 #include <proto/dos.h>
25 AROS_LH4(BOOL
, SetVar
,
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
),
34 struct DosLibrary
*, DOSBase
, 150, Dos
)
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
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
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
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
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
78 Zero if this function failed, non-zero otherwise.
81 It is possible to have two variables with the same name as
82 long as they have different types.
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:.
93 DeleteVar(), FindVar(), GetVar(),
96 See FindVar() for a description of the inner workings of local
99 *****************************************************************************/
106 /* Local variable is default. */
107 if((flags
& GVF_GLOBAL_ONLY
) == 0)
109 ULONG nameLen
= strlen(name
);
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
);
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
);
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
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
,
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)
166 if (NULL
!= n
->lv_Node
.ln_Succ
)
168 Insert((struct List
*)&pr
->pr_LocalVars
,
170 (struct Node
*) n
->lv_Node
.ln_Pred
);
174 AddTail((struct List
*)&pr
->pr_LocalVars
,
181 /* -1 as size means: buffer contains a null-terminated string */
184 /* Do NOT add 1 byte to account for the NUL char, AmigaOS(R) doesn't
186 lv
->lv_Len
= strlen(buffer
);
193 /* now get some memory for the value, this will implicitly set NULL if lv_Len is 0 */
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
)
200 } /* set a local variable */
202 /* Ok, try and set a global variable. */
203 if ((flags
& GVF_LOCAL_ONLY
) == 0)
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
);
217 /* Write the data to the file */
218 /* size = -1 means that the value is a null-terminated
222 Write(file
, buffer
, strlen(buffer
));
226 Write(file
, buffer
, size
);
236 /* Let's see whether we're supposed to make a copy of this to
239 if (0 != (flags
& GVF_SAVE_VAR
))
241 CopyMem("ENVARC:", nameBuffer
, 8);
242 AddPart(nameBuffer
, name
, 384);
244 file
= Open(nameBuffer
, MODE_NEWFILE
);
248 /* Write the data to the file */
249 /* size = -1 means that the value is a null-terminated
253 Write(file
, buffer
, strlen(buffer
));
257 Write(file
, buffer
, size
);
264 /* We created both, bye bye */
266 } /* try a global variable */
267 } /* input was valid */