|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.