BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / cfe / cfe / main / env_subr.c
blobb1b6a5be6ea55d6b5f6a30736d76a1ee5d11746e
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Environment variable subroutines File: env_subr.c
5 *
6 * This module contains routines to muck with environment variables
7 * (manage the list, read/write to nvram, etc.)
8 *
9 * Author: Mitch Lichtenberg (mpl@broadcom.com)
11 *********************************************************************
13 * Copyright 2000,2001,2002,2003
14 * Broadcom Corporation. All rights reserved.
16 * This software is furnished under license and may be used and
17 * copied only in accordance with the following terms and
18 * conditions. Subject to these conditions, you may download,
19 * copy, install, use, modify and distribute modified or unmodified
20 * copies of this software in source and/or binary form. No title
21 * or ownership is transferred hereby.
23 * 1) Any source code used, modified or distributed must reproduce
24 * and retain this copyright notice and list of conditions
25 * as they appear in the source file.
27 * 2) No right is granted to use any trade name, trademark, or
28 * logo of Broadcom Corporation. The "Broadcom Corporation"
29 * name may not be used to endorse or promote products derived
30 * from this software without the prior written permission of
31 * Broadcom Corporation.
33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGE.
46 ********************************************************************* */
48 #include "lib_types.h"
49 #include "lib_string.h"
50 #include "lib_queue.h"
51 #include "lib_malloc.h"
52 #include "lib_printf.h"
54 #include "env_subr.h"
55 #include "nvram_subr.h"
57 #include "cfe_error.h"
58 #include "cfe.h"
60 #ifdef EB332
61 extern void setenv (char *e, char *v, int rewrite);
62 #endif
63 /* *********************************************************************
64 * Types
65 ********************************************************************* */
67 typedef struct cfe_envvar_s {
68 queue_t qb;
69 int flags;
70 char *name;
71 char *value;
72 /* name and value go here */
73 } cfe_envvar_t;
75 /* *********************************************************************
76 * Globals
77 ********************************************************************* */
79 queue_t env_envvars = {&env_envvars,&env_envvars};
80 extern unsigned int cfe_startflags;
82 /* *********************************************************************
83 * env_findenv(name)
85 * Locate an environment variable in the in-memory list
87 * Input parameters:
88 * name - name of env var to find
90 * Return value:
91 * cfe_envvar_t pointer, or NULL if not found
92 ********************************************************************* */
94 static cfe_envvar_t *env_findenv(const char *name)
96 queue_t *qb;
97 cfe_envvar_t *env;
99 for (qb = env_envvars.q_next; qb != &env_envvars; qb = qb->q_next) {
100 env = (cfe_envvar_t *) qb;
101 if (strcmp(env->name,name) == 0) break;
104 if (qb == &env_envvars) return NULL;
106 return (cfe_envvar_t *) qb;
110 /* *********************************************************************
111 * env_enum(idx,name,namelen,val,vallen)
113 * Enumerate environment variables. This routine locates
114 * the nth environment variable and copies its name and value
115 * to user buffers.
117 * The namelen and vallen variables must be preinitialized to
118 * the maximum size of the output buffer.
120 * Input parameters:
121 * idx - variable index to find (starting with zero)
122 * name,namelen - name buffer and length
123 * val,vallen - value buffer and length
125 * Return value:
126 * 0 if ok
127 * else error code
128 ********************************************************************* */
130 int env_enum(int idx,char *name,int *namelen,char *val,int *vallen)
132 queue_t *qb;
133 cfe_envvar_t *env;
135 for (qb = env_envvars.q_next; qb != &env_envvars; qb = qb->q_next) {
136 if (idx == 0) break;
137 idx--;
140 if (qb == &env_envvars) return CFE_ERR_ENVNOTFOUND;
141 env = (cfe_envvar_t *) qb;
143 *namelen = xstrncpy(name,env->name,*namelen);
144 *vallen = xstrncpy(val,env->value,*vallen);
146 return 0;
150 /* *********************************************************************
151 * env_envtype(name)
153 * Return the type of the environment variable
155 * Input parameters:
156 * name - name of environment variable
158 * Return value:
159 * flags, or <0 if error occured
160 ********************************************************************* */
161 int env_envtype(const char *name)
163 cfe_envvar_t *env;
165 env = env_findenv(name);
167 if (env) {
168 return env->flags;
171 return CFE_ERR_ENVNOTFOUND;
176 /* *********************************************************************
177 * env_delenv(name)
179 * Delete an environment variable
181 * Input parameters:
182 * name - environment variable to delete
184 * Return value:
185 * 0 if ok
186 * else error code
187 ********************************************************************* */
189 int env_delenv(const char *name)
191 cfe_envvar_t *env;
193 env = env_findenv(name);
195 if (!env) return 0;
197 if (!(env->flags & ENV_FLG_READONLY)) {
198 q_dequeue((queue_t *) env);
199 KFREE(env);
200 return 0;
203 return CFE_ERR_ENVNOTFOUND;
206 /* *********************************************************************
207 * env_getenv(name)
209 * Retrieve the value of an environment variable
211 * Input parameters:
212 * name - name of environment variable to find
214 * Return value:
215 * value, or NULL if variable is not found
216 ********************************************************************* */
218 char *env_getenv(const char *name)
220 cfe_envvar_t *env;
222 env = env_findenv(name);
224 if (env) {
225 return env->value;
228 return NULL;
232 /* *********************************************************************
233 * env_setenv(name,value,flags)
235 * Set the value of an environment variable
237 * Input parameters:
238 * name - name of variable
239 * value - value of variable
240 * flags - flags for variable (ENV_FLG_xxx)
242 * Return value:
243 * 0 if ok
244 * else error code
245 ********************************************************************* */
247 int env_setenv(const char *name,char *value,int flags)
249 cfe_envvar_t *env;
250 int namelen;
252 env = env_findenv(name);
253 if (env) {
254 if (!(flags & ENV_FLG_ADMIN)) {
255 if (env->flags & ENV_FLG_READONLY) return CFE_ERR_ENVREADONLY;
257 q_dequeue((queue_t *) env);
258 KFREE(env);
261 namelen = strlen(name);
263 env = KMALLOC(sizeof(cfe_envvar_t) + namelen + 1 + strlen(value) + 1,0);
264 if (!env) return CFE_ERR_NOMEM;
266 env->name = (char *) (env+1);
267 env->value = env->name + namelen + 1;
268 env->flags = (flags & ENV_FLG_MASK);
270 strcpy(env->name,name);
271 strcpy(env->value,value);
273 q_enqueue(&env_envvars,(queue_t *) env);
275 return 0;
279 /* *********************************************************************
280 * env_load()
282 * Load the environment from the NVRAM device.
284 * Input parameters:
285 * nothing
287 * Return value:
288 * 0 if ok
289 * else error code
290 ********************************************************************* */
293 int env_load(void)
295 int size;
296 char *buffer;
297 char *ptr;
298 char *envval;
299 unsigned int reclen;
300 unsigned int rectype;
301 int offset;
302 int flg;
303 int retval = -1;
304 char valuestr[256];
307 * If in 'safe mode', don't read the environment the first time.
310 if (cfe_startflags & CFE_INIT_SAFE) {
311 cfe_startflags &= ~CFE_INIT_SAFE;
312 return 0;
315 flg = nvram_open();
316 if (flg < 0) return flg;
318 size = nvram_getsize();
319 buffer = KMALLOC(size,0);
321 if (buffer == NULL) return CFE_ERR_NOMEM;
323 ptr = buffer;
324 offset = 0;
326 /* Read the record type and length */
327 if (nvram_read(ptr,offset,1) != 1) {
328 retval = CFE_ERR_IOERR;
329 goto error;
332 while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
334 /* Adjust pointer for TLV type */
335 rectype = *(ptr);
336 offset++;
337 size--;
340 * Read the length. It can be either 1 or 2 bytes
341 * depending on the code
343 if (rectype & ENV_LENGTH_8BITS) {
344 /* Read the record type and length - 8 bits */
345 if (nvram_read(ptr,offset,1) != 1) {
346 retval = CFE_ERR_IOERR;
347 goto error;
349 reclen = *(ptr);
350 size--;
351 offset++;
353 else {
354 /* Read the record type and length - 16 bits, MSB first */
355 if (nvram_read(ptr,offset,2) != 2) {
356 retval = CFE_ERR_IOERR;
357 goto error;
359 reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
360 size -= 2;
361 offset += 2;
364 if (reclen > size) break; /* should not happen, bad NVRAM */
366 switch (rectype) {
367 case ENV_TLV_TYPE_ENV:
368 /* Read the TLV data */
369 if (nvram_read(ptr,offset,reclen) != reclen) goto error;
370 flg = *ptr++;
371 envval = strnchr((char *)ptr,'=',(reclen-1));
372 if (envval) {
373 *envval++ = '\0';
374 memcpy(valuestr,envval,(reclen-1)-(envval-ptr));
375 valuestr[(reclen-1)-(envval-ptr)] = '\0';
376 env_setenv((char *)ptr,valuestr,flg);
378 break;
380 default:
381 /* Unknown TLV type, skip it. */
382 break;
386 * Advance to next TLV
389 size -= (int)reclen;
390 offset += reclen;
392 /* Read the next record type */
393 ptr = buffer;
394 if (nvram_read(ptr,offset,1) != 1) goto error;
397 retval = 0; /* success! */
399 error:
400 KFREE(buffer);
401 nvram_close();
403 return retval;
408 /* *********************************************************************
409 * env_save()
411 * Write the environment to the NVRAM device.
413 * Input parameters:
414 * nothing
416 * Return value:
417 * 0 if ok, else error code
418 ********************************************************************* */
420 int env_save(void)
422 int size;
423 unsigned char *buffer;
424 unsigned char *buffer_end;
425 unsigned char *ptr;
426 queue_t *qb;
427 cfe_envvar_t *env;
428 int namelen;
429 int valuelen;
430 int flg;
432 flg = nvram_open();
433 if (flg < 0) return flg;
435 nvram_erase();
437 size = nvram_getsize();
438 buffer = KMALLOC(size,0);
440 if (buffer == NULL) return CFE_ERR_NOMEM;
442 buffer_end = buffer + size;
444 ptr = buffer;
446 for (qb = env_envvars.q_next; qb != &env_envvars; qb = qb->q_next) {
447 env = (cfe_envvar_t *) qb;
449 if (env->flags & (ENV_FLG_BUILTIN)) continue;
451 namelen = strlen(env->name);
452 valuelen = strlen(env->value);
454 if ((ptr + 2 + namelen + valuelen + 1 + 1 + 1) > buffer_end) break;
456 *ptr++ = ENV_TLV_TYPE_ENV; /* TLV record type */
457 *ptr++ = (namelen + valuelen + 1 + 1); /* TLV record length */
459 *ptr++ = (unsigned char)env->flags;
460 memcpy(ptr,env->name,namelen); /* TLV record data */
461 ptr += namelen;
462 *ptr++ = '=';
463 memcpy(ptr,env->value,valuelen);
464 ptr += valuelen;
465 #ifdef EB332
466 setenv(env->name, env->value, 1);
467 #endif
471 *ptr++ = ENV_TLV_TYPE_END;
473 size = nvram_write((char *)buffer,0,ptr-buffer);
475 KFREE(buffer);
477 nvram_close();
479 return (size == (ptr-buffer)) ? 0 : CFE_ERR_IOERR;