|
|
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.