optional icu diff.
[AROS.git] / rom / dos / getvar.c
blobf213b4b22b6312fce9bc09afe4e4aa1d8979b955
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: GetVar - Return the value of a local or global variable.
6 Lang: English
7 */
9 #include <aros/debug.h>
10 #include <dos/dos.h>
11 #include <proto/exec.h>
12 #include "dos_intern.h"
14 static LONG getvar_from(const char *name, const char *volume, STRPTR buffer, LONG size, LONG flags, struct DosLibrary *DOSBase);
16 /*****************************************************************************
18 NAME */
19 #include <dos/var.h>
20 #include <proto/dos.h>
22 AROS_LH4(LONG, GetVar,
24 /* SYNOPSIS */
25 AROS_LHA(CONST_STRPTR, name, D1),
26 AROS_LHA(STRPTR, buffer, D2),
27 AROS_LHA(LONG, size, D3),
28 AROS_LHA(LONG, flags, D4),
30 /* LOCATION */
31 struct DosLibrary *, DOSBase, 151, Dos)
33 /* FUNCTION
34 This function will return the value of a local or environmental
35 variable in the supplied buffer.
37 It is advised to only use ASCII characters with a variable, but
38 this is not required.
40 If GVF_BINARY_VAR is not specified, this function will stop putting
41 characters into the destination buffer when a '\n' is hit, or the
42 end of the buffer is reached. Otherwise it will complete fill the
43 buffer.
45 INPUTS
46 name - the name of the variable you want.
47 buffer - Space to store the returned variable.
48 size - Length of the buffer in bytes.
49 flags - A combination of the type of variable to get (lower
50 8 bits) and flags that control the value of this
51 function. Current flags are:
53 GVF_GLOBAL_ONLY - only tries to get a global variable.
54 GVF_LOCAL_ONLY - only tries to get a local variable.
55 GVF_BINARY_VAR - do not stop at a '\n' character.
56 GVF_DONT_NULL_TERM - no NULL termination. This only
57 applies to GVF_BINARY_VAR.
59 RESULT
60 Will return the number of characters put in the buffer, or -1
61 if the variable is not defined. The '\n' character if it exists
62 will not be placed in the buffer.
64 If the value would overflow the user buffer, then the number of
65 characters copied into the buffer will be returned and the buffer
66 truncated.The buffer will be NULL terminated unless
67 GVF_DONT_NULL_TERM is set.
69 IoErr() will contain either:
70 ERROR_OBJECT_NOT_FOUND
71 if the variable is not defined.
72 ERROR_BAD_NUMBER
73 if the size of the buffer is 0.
74 the total length of the variable
75 otherwise.
77 NOTES
79 EXAMPLE
81 BUGS
82 LV_VAR is the only type that can be global.
84 SEE ALSO
85 DeleteVar(), FindVar(), SetVar()
87 INTERNALS
88 Redo the RESULT documentation.
90 *****************************************************************************/
92 AROS_LIBFUNC_INIT
94 D(bug("GetVar: name = \"%s\", buffer = $%lx, size = %ld, flags = $%lx\n",
95 name, buffer, size, flags));
97 if (0 == size)
99 D(bug("GetVar: bad size\n"));
101 SetIoErr(ERROR_BAD_NUMBER);
103 return 0;
106 if (name && buffer)
108 /* not global only? */
109 if(0 == (flags & GVF_GLOBAL_ONLY))
111 /* look for a local variable */
112 struct LocalVar *lv;
114 D(bug("GetVar: Local variable\n"));
115 /* look for a variable of the given name */
116 lv = FindVar(name, flags);
118 if (lv)
120 int i;
121 /* which size is shorter: the buffer or the size of
122 the value? */
123 i = (size < lv->lv_Len) ? size : lv->lv_Len;
124 CopyMem(lv->lv_Value, buffer, i);
126 /* were we supposed to stop after the first "\n"?
127 = No GVF_BINARY_VAR and no GVF_DONT_NULL_TERM
129 if (0 == (flags & GVF_BINARY_VAR))
131 int j = 0;
133 while ((buffer[j] != '\n') && (j < i))
135 j++;
138 if (j == size)
140 j = size - 1;
143 buffer[j]= 0x0; /* mark end of string */
144 size = j;
146 else if (0 == (flags & GVF_DONT_NULL_TERM))
148 if (i == size)
150 i = size - 1;
153 buffer[i] = 0x0; /* mark end of string */
154 size = i;
156 else
158 size = i;
161 SetIoErr(lv->lv_Len);
162 D(bug("GetVar: return %d\n", size));
164 return size;
165 } /* Got lv */
166 } /* !global only */
168 /****** GLOBAL VARIABLE TREATMENT ******/
170 if ((flags & 0xff) == LV_VAR && !(flags & GVF_LOCAL_ONLY))
172 LONG ret;
174 /* as standard: look for the file in ENV: if no path is
175 * given in the variable
177 ret = getvar_from(name, "ENV:", buffer, size, flags, DOSBase);
179 if (ret >= 0)
180 return ret;
182 /* If not found in ENV:, look in ENVARC: */
183 ret = getvar_from(name, "ENVARC:", buffer, size, flags, DOSBase);
185 if (ret >= 0)
186 return ret;
188 } /* ! local file only */
189 } /* name and buffer */
191 D(bug("GetVar: not found\n"));
193 SetIoErr(ERROR_OBJECT_NOT_FOUND);
195 return -1;
197 AROS_LIBFUNC_EXIT
198 } /* GetVar */
201 static LONG getvar_from(const char *name, const char *volume, STRPTR buffer, LONG size, LONG flags, struct DosLibrary *DOSBase)
203 BPTR file;
204 LONG i;
206 UBYTE filebuf[256];
208 strncpy(filebuf, volume, sizeof(filebuf));
209 /* Just being paranoid here */
210 filebuf[sizeof(filebuf)-1]=0;
212 AddPart(filebuf, name, 256);
213 D(bug("GetVar: Global variable: %s\n", filebuf));
214 file = Open(filebuf, MODE_OLDFILE);
216 if (file) /* file could be opened */
218 ULONG fSize;
219 struct FileInfoBlock fib;
221 if (ExamineFH(file, &fib))
223 /* fSize now contains the size of variable. */
224 fSize = fib.fib_Size;
226 else
228 D(bug("GetVar: can't find size\n"));
230 return -1;
233 /* We return the number of bytes actually read. */
234 i = Read(file, buffer, size);
235 Close(file);
237 /* were we supposed to stop after the first "\n"?
238 = No GVF_BINARY_VAR and no GVF_DONT_NULL_TERM */
239 if (0 == (flags & GVF_BINARY_VAR))
241 int j = 0;
242 /* lets search for the first '\n' (if any) in the
243 * string and replace it by '\0'. */
244 while ((buffer[j] != '\n') && (j < i))
246 j++;
249 if (j == size)
251 j = size - 1;
254 buffer[j]= '\0'; /* mark end of string */
255 size = j;
257 else if (0 == (flags & GVF_DONT_NULL_TERM))
259 if (i == size)
261 i = size - 1;
264 buffer[i] = 0x0; /* mark end of string */
265 size = i;
267 else
269 size = i;
272 SetIoErr(fSize);
273 D(bug("GetVar: return %d\n", size));
275 return size;
276 } /* open(file) */
278 return -1;