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