Annotation of qemu/roms/SLOF/lib/libnvram/envvar.c, revision 1.1.1.2

1.1       root        1: /******************************************************************************
                      2:  * Copyright (c) 2004, 2008 IBM Corporation
                      3:  * All rights reserved.
                      4:  * This program and the accompanying materials
                      5:  * are made available under the terms of the BSD License
                      6:  * which accompanies this distribution, and is available at
                      7:  * http://www.opensource.org/licenses/bsd-license.php
                      8:  *
                      9:  * Contributors:
                     10:  *     IBM Corporation - initial implementation
                     11:  *****************************************************************************/
                     12: 
                     13: #include <stdint.h>
                     14: #include "../libc/include/stdio.h"
                     15: #include "../libc/include/string.h"
                     16: #include "../libc/include/stdlib.h"
                     17: #include "nvram.h"
                     18: 
                     19: /* returns the offset of the first byte after the searched envvar */
                     20: static int get_past_env_pos(partition_t part, char *envvar)
                     21: {
                     22:        int offset, len;
                     23:        static char temp[256];
                     24:        uint8_t data;
                     25: 
                     26:        offset=part.addr;
                     27: 
                     28:        memset(temp, 0, 256);
                     29: 
                     30:        do {
                     31:                len=0;
                     32:                while((data=nvram_read_byte(offset++)) && len < 256) {
                     33:                        temp[len++]=data;
                     34:                }
                     35:                if (!strncmp(envvar, temp, strlen(envvar))) {
                     36:                        return offset;
                     37:                }
                     38:        } while (len);
                     39: 
                     40:        return -1;
                     41: }
                     42: 
                     43: /**
                     44:  * @param partition name of the envvar partition
                     45:  * @param envvar name of the environment variable
                     46:  * @return pointer to temporary string containing the value of envvar
                     47:  */
                     48: 
                     49: char *get_env(partition_t part, char *envvar)
                     50: {
                     51:        static char temp[256+1];
                     52:        int len, offset;
                     53:        uint8_t data;
                     54: 
                     55:        DEBUG("get_env %s... ", envvar);
                     56:        if(!part.addr) {
                     57:                /* ERROR: No environment variable partition */
                     58:                DEBUG("invalid partition.\n");
                     59:                return NULL;
                     60:        }
                     61: 
                     62:        offset=part.addr;
                     63: 
                     64:        do {
                     65:                len=0;
                     66:                while((data=nvram_read_byte(offset++)) && len < 256) {
                     67:                        temp[len++]=data;
                     68:                }
                     69:                temp[len]=0;
                     70: 
                     71:                if (!strncmp(envvar, temp, strlen(envvar))) {
                     72:                        int pos=0;
                     73:                        while (temp[pos]!='=' && pos < len) pos++;
                     74:                        // DEBUG("value='%s'\n", temp+pos+1); 
                     75:                        return temp+pos+1;
                     76:                }
                     77:        } while (len);
                     78: 
                     79:        DEBUG("not found\n");
                     80:        return NULL;
                     81: }
                     82: 
                     83: static int find_last_envvar(partition_t part)
                     84: {
                     85:        uint8_t last, current;
1.1.1.2 ! root       86:        int offset;
1.1       root       87: 
                     88:        offset=part.addr;
                     89: 
                     90:        last=nvram_read_byte(part.addr);
                     91: 
                     92:        for (offset=part.addr; offset<(int)(part.addr+part.len); offset++) {
                     93:                current=nvram_read_byte(offset);
                     94:                if(!last && !current)
                     95:                        return offset;
                     96: 
                     97:                last=current;
                     98:        }
                     99: 
                    100:        return -1;
                    101: }
                    102: 
                    103: int add_env(partition_t part, char *envvar, char *value)
                    104: {
                    105:        int freespace, last, len, offset;
                    106:        unsigned int i;
                    107: 
                    108:        /* Find offset where we can write */
                    109:        last = find_last_envvar(part);
                    110: 
                    111:        /* How much space do we have left? */
                    112:        freespace = part.addr+part.len-last;
                    113: 
                    114:        /* how long is the entry we want to write? */
                    115:        len = strlen(envvar) + strlen(value) + 2;
                    116: 
                    117:        if(freespace<len) {
                    118:                // TODO try to increase partition size
                    119:                return -1;
                    120:        }
                    121: 
                    122:        offset=last;
                    123: 
                    124:        for(i=0; i<strlen(envvar); i++)
                    125:                nvram_write_byte(offset++, envvar[i]);
                    126: 
                    127:        nvram_write_byte(offset++, '=');
                    128: 
                    129:        for(i=0; i<strlen(value); i++)
                    130:                nvram_write_byte(offset++, value[i]);
                    131: 
                    132:        return 0;
                    133: }
                    134: 
                    135: int del_env(partition_t part, char *envvar)
                    136: {
                    137:        int last, current, pos, i;
                    138:        char *buffer;
                    139: 
                    140:        if(!part.addr)
                    141:                return -1;
                    142: 
                    143:        last=find_last_envvar(part);
                    144:        current = pos = get_past_env_pos(part, envvar);
                    145:        
                    146:        // TODO is this really required?
                    147:        /* go back to non-0 value */
                    148:        current--;
                    149: 
                    150:        while (nvram_read_byte(current))
                    151:                current--;
                    152: 
                    153:        // TODO is this required?
                    154:        current++;
                    155: 
                    156:        buffer=get_nvram_buffer(last-pos);
                    157: 
                    158:        for (i=0; i<last-pos; i++)
                    159:                buffer[i]=nvram_read_byte(i+pos);
                    160: 
                    161:        for (i=0; i<last-pos; i++)
                    162:                nvram_write_byte(i+current, buffer[i]);
                    163: 
                    164:        free_nvram_buffer(buffer);
                    165: 
                    166:        erase_nvram(last, current+last-pos);
                    167: 
                    168:        return 0;
                    169: }
                    170: 
                    171: int set_env(partition_t part, char *envvar, char *value)
                    172: {
                    173:        char *oldvalue, *buffer;
                    174:        int last, current, buffersize, i;
                    175: 
                    176:        DEBUG("set_env %lx[%lx]: %s=%s\n", part.addr, part.len, envvar, value);
                    177: 
                    178:        if(!part.addr)
                    179:                return -1;
                    180: 
                    181:        /* Check whether the environment variable exists already */
                    182:        oldvalue = get_env(part, envvar);
                    183: 
                    184:        if(oldvalue==NULL)
                    185:                return add_env(part, envvar, value);
                    186: 
                    187: 
                    188:        /* The value did not change. So we succeeded! */
                    189:        if(!strncmp(oldvalue, value, strlen(value)+1))
                    190:                return 0;
                    191: 
                    192:        /* we need to overwrite environment variables, back them up first */
                    193: 
                    194:        // DEBUG("overwriting existing environment variable\n");
                    195: 
                    196:        /* allocate a buffer */
                    197:        last=find_last_envvar(part);
                    198:        current=get_past_env_pos(part, envvar);
                    199:        buffersize = last - current;
                    200:        buffer=get_nvram_buffer(buffersize);
                    201:        if(!buffer)
                    202:                return -1;
                    203: 
                    204:        for (i=0; i<buffersize; i++) {
                    205:                buffer[i] = nvram_read_byte(current+i);
                    206:        }
                    207: 
                    208:        /* walk back until the = */
                    209:        while (nvram_read_byte(current)!='=') {
                    210:                current--;
                    211:        }
                    212: 
                    213:        /* Start at envvar= */
                    214:        current++;
                    215: 
                    216:        /* Write the new value */
                    217:        for(i=0; i<(int)strlen(value); i++) {
                    218:                nvram_write_byte(current++, value[i]);
                    219:        }
                    220:        
                    221:        /* Write end of string marker */
                    222:        nvram_write_byte(current++, 0);
                    223: 
                    224:        /* Copy back the buffer */
                    225:        for (i=0; i<buffersize; i++) {
                    226:                nvram_write_byte(current++, buffer[i]);
                    227:        }
                    228: 
                    229:        free_nvram_buffer(buffer);
                    230: 
                    231:        /* If the new environment variable content is shorter than the old one,
                    232:         * we need to erase the rest of the bytes 
                    233:         */
                    234: 
                    235:        if (current<last) {
                    236:                for(i=current; i<last; i++) {
                    237:                        nvram_write_byte(i, 0);
                    238:                }
                    239:        }
                    240: 
                    241:        return 0; /* success */
                    242: }
                    243: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.