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

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;
        !            86:        int offset, len;
        !            87: 
        !            88:        offset=part.addr;
        !            89:        len=part.len;
        !            90: 
        !            91:        last=nvram_read_byte(part.addr);
        !            92: 
        !            93:        for (offset=part.addr; offset<(int)(part.addr+part.len); offset++) {
        !            94:                current=nvram_read_byte(offset);
        !            95:                if(!last && !current)
        !            96:                        return offset;
        !            97: 
        !            98:                last=current;
        !            99:        }
        !           100: 
        !           101:        return -1;
        !           102: }
        !           103: 
        !           104: int add_env(partition_t part, char *envvar, char *value)
        !           105: {
        !           106:        int freespace, last, len, offset;
        !           107:        unsigned int i;
        !           108: 
        !           109:        /* Find offset where we can write */
        !           110:        last = find_last_envvar(part);
        !           111: 
        !           112:        /* How much space do we have left? */
        !           113:        freespace = part.addr+part.len-last;
        !           114: 
        !           115:        /* how long is the entry we want to write? */
        !           116:        len = strlen(envvar) + strlen(value) + 2;
        !           117: 
        !           118:        if(freespace<len) {
        !           119:                // TODO try to increase partition size
        !           120:                return -1;
        !           121:        }
        !           122: 
        !           123:        offset=last;
        !           124: 
        !           125:        for(i=0; i<strlen(envvar); i++)
        !           126:                nvram_write_byte(offset++, envvar[i]);
        !           127: 
        !           128:        nvram_write_byte(offset++, '=');
        !           129: 
        !           130:        for(i=0; i<strlen(value); i++)
        !           131:                nvram_write_byte(offset++, value[i]);
        !           132: 
        !           133:        return 0;
        !           134: }
        !           135: 
        !           136: int del_env(partition_t part, char *envvar)
        !           137: {
        !           138:        int last, current, pos, i;
        !           139:        char *buffer;
        !           140: 
        !           141:        if(!part.addr)
        !           142:                return -1;
        !           143: 
        !           144:        last=find_last_envvar(part);
        !           145:        current = pos = get_past_env_pos(part, envvar);
        !           146:        
        !           147:        // TODO is this really required?
        !           148:        /* go back to non-0 value */
        !           149:        current--;
        !           150: 
        !           151:        while (nvram_read_byte(current))
        !           152:                current--;
        !           153: 
        !           154:        // TODO is this required?
        !           155:        current++;
        !           156: 
        !           157:        buffer=get_nvram_buffer(last-pos);
        !           158: 
        !           159:        for (i=0; i<last-pos; i++)
        !           160:                buffer[i]=nvram_read_byte(i+pos);
        !           161: 
        !           162:        for (i=0; i<last-pos; i++)
        !           163:                nvram_write_byte(i+current, buffer[i]);
        !           164: 
        !           165:        free_nvram_buffer(buffer);
        !           166: 
        !           167:        erase_nvram(last, current+last-pos);
        !           168: 
        !           169:        return 0;
        !           170: }
        !           171: 
        !           172: int set_env(partition_t part, char *envvar, char *value)
        !           173: {
        !           174:        char *oldvalue, *buffer;
        !           175:        int last, current, buffersize, i;
        !           176: 
        !           177:        DEBUG("set_env %lx[%lx]: %s=%s\n", part.addr, part.len, envvar, value);
        !           178: 
        !           179:        if(!part.addr)
        !           180:                return -1;
        !           181: 
        !           182:        /* Check whether the environment variable exists already */
        !           183:        oldvalue = get_env(part, envvar);
        !           184: 
        !           185:        if(oldvalue==NULL)
        !           186:                return add_env(part, envvar, value);
        !           187: 
        !           188: 
        !           189:        /* The value did not change. So we succeeded! */
        !           190:        if(!strncmp(oldvalue, value, strlen(value)+1))
        !           191:                return 0;
        !           192: 
        !           193:        /* we need to overwrite environment variables, back them up first */
        !           194: 
        !           195:        // DEBUG("overwriting existing environment variable\n");
        !           196: 
        !           197:        /* allocate a buffer */
        !           198:        last=find_last_envvar(part);
        !           199:        current=get_past_env_pos(part, envvar);
        !           200:        buffersize = last - current;
        !           201:        buffer=get_nvram_buffer(buffersize);
        !           202:        if(!buffer)
        !           203:                return -1;
        !           204: 
        !           205:        for (i=0; i<buffersize; i++) {
        !           206:                buffer[i] = nvram_read_byte(current+i);
        !           207:        }
        !           208: 
        !           209:        /* walk back until the = */
        !           210:        while (nvram_read_byte(current)!='=') {
        !           211:                current--;
        !           212:        }
        !           213: 
        !           214:        /* Start at envvar= */
        !           215:        current++;
        !           216: 
        !           217:        /* Write the new value */
        !           218:        for(i=0; i<(int)strlen(value); i++) {
        !           219:                nvram_write_byte(current++, value[i]);
        !           220:        }
        !           221:        
        !           222:        /* Write end of string marker */
        !           223:        nvram_write_byte(current++, 0);
        !           224: 
        !           225:        /* Copy back the buffer */
        !           226:        for (i=0; i<buffersize; i++) {
        !           227:                nvram_write_byte(current++, buffer[i]);
        !           228:        }
        !           229: 
        !           230:        free_nvram_buffer(buffer);
        !           231: 
        !           232:        /* If the new environment variable content is shorter than the old one,
        !           233:         * we need to erase the rest of the bytes 
        !           234:         */
        !           235: 
        !           236:        if (current<last) {
        !           237:                for(i=current; i<last; i++) {
        !           238:                        nvram_write_byte(i, 0);
        !           239:                }
        !           240:        }
        !           241: 
        !           242:        return 0; /* success */
        !           243: }
        !           244: 

unix.superglobalmegacorp.com

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