1: #include "global.h"
2: #include "ub_env.h"
3:
4:
5: env_t *env;
6:
7: static int
8: ub_flash_io(const char *csSec, int mode)
9: {
10: int f, l, rlen;
11: const char *str;
12: ssize_t siz, esiz;
13: ait_val_t v;
14: u_int crc;
15:
16: FTRACE(4);
17:
18: str = cfg_getAttribute(&cfg, csSec, "drive_size");
19: siz = strtol(str, NULL, 0);
20: if (!siz)
21: return -1;
22: str = cfg_getAttribute(&cfg, csSec, "env_size");
23: if (!str)
24: esiz = siz - sizeof env->env_crc;
25: else
26: esiz = strtol(str, NULL, 0);
27: str = cfg_getAttribute(&cfg, csSec, "drive_name");
28: if (!str) {
29: printf("Error:: drive not found!\n");
30: return -1;
31: }
32:
33: cfg_loadAttribute(&cfg, "ube", "lock", &v, UBE_LOCK);
34: l = open(AIT_GET_STR(&v), O_CREAT | O_EXCL | O_WRONLY, 0644);
35: if (l == -1) {
36: printf("Error:: Locked u-boot-env map %s\n", AIT_GET_STR(&v));
37: AIT_FREE_VAL(&v);
38: return -1;
39: }
40:
41: f = open(str, mode);
42: if (f == -1) {
43: printf("Error:: Can't access u-boot-env device %s\n", str);
44: close(l);
45: unlink(AIT_GET_STR(&v));
46: AIT_FREE_VAL(&v);
47: return -1;
48: }
49:
50: if (mode & O_RDWR) {
51: env->env_crc = crc32(0, (u_char*) env->env_data, esiz);
52: rlen = write(f, env, siz);
53: if (rlen != siz)
54: printf("Error:: written %d bytes != %d\n", rlen, siz);
55: else
56: VERB(3) printf("Written %d bytes\n", rlen);
57: lseek(f, 0, SEEK_SET);
58: }
59:
60: rlen = read(f, env, siz);
61: if (rlen != siz)
62: printf("Error:: readed %d bytes != %d\n", rlen, siz);
63: else
64: VERB(3) printf("Readed %d bytes\n", rlen);
65:
66: crc = crc32(0, (u_char*) env->env_data, esiz);
67: if (crc != env->env_crc)
68: VERB(1) printf("Warning:: Bad CRC, Flash crc32 0x%x != 0x%x\n",
69: env->env_crc, crc);
70:
71: close(f);
72: close(l);
73: unlink(AIT_GET_STR(&v));
74: AIT_FREE_VAL(&v);
75: return 0;
76: }
77:
78: static inline const char *
79: ub_envmatch(const char *csName, const char *e)
80: {
81: while (*csName == *e++)
82: if (*csName++ == '=')
83: return e;
84: if (!*csName && *(e - 1) == '=')
85: return e;
86:
87: return NULL;
88: }
89:
90: int
91: ub_load(const char *csSec)
92: {
93: const char *str;
94: size_t siz;
95:
96: FTRACE(4);
97:
98: str = cfg_getAttribute(&cfg, csSec, "drive_size");
99: siz = strtol(str, NULL, 0);
100: if (!siz)
101: return -1;
102:
103: env = e_malloc(siz);
104: if (!env) {
105: ELIBERR(elwix);
106: return -1;
107: }
108:
109: return ub_flash_io(csSec, O_RDONLY);
110: }
111:
112: void
113: ub_unload()
114: {
115: FTRACE(4);
116:
117: if (env)
118: e_free(env);
119: }
120:
121: const char*
122: ub_getenv(const char *csSec, const char *csName)
123: {
124: char *e, *nxt;
125: size_t dlen = 0;
126: const char *str = NULL;
127:
128: FTRACE(3);
129:
130: str = cfg_getAttribute(&cfg, csSec, "env_size");
131: if (!str) {
132: str = cfg_getAttribute(&cfg, csSec, "drive_size");
133: if (!str)
134: return NULL;
135: dlen -= sizeof env->env_crc;
136: }
137: dlen += strtol(str, NULL, 0);
138: if (!dlen)
139: return NULL;
140: else
141: dlen--;
142:
143: for (e = env->env_data; *e; e = nxt + 1) {
144: for (nxt = e; *nxt; nxt++)
145: if (nxt >= env->env_data + dlen) {
146: printf("Error:: environment not terminated\n");
147: return NULL;
148: }
149:
150: str = ub_envmatch(csName, e);
151: if (str)
152: break;
153: }
154:
155: return str;
156: }
157:
158: int
159: ub_setenv(const char *csSec, const char *csName, const char *csValue)
160: {
161: char *e, *nxt;
162: ssize_t dlen = 0, len;
163: const char *str, *old = NULL;
164:
165: FTRACE(3);
166:
167: str = cfg_getAttribute(&cfg, csSec, "env_size");
168: if (!str) {
169: str = cfg_getAttribute(&cfg, csSec, "drive_size");
170: if (!str)
171: return -1;
172: dlen -= sizeof env->env_crc;
173: }
174: dlen += strtol(str, NULL, 0);
175: if (!dlen)
176: return -1;
177: else
178: dlen--;
179:
180: for (e = env->env_data; *e; e = nxt + 1) {
181: for (nxt = e; *nxt; nxt++)
182: if (nxt >= env->env_data + dlen) {
183: printf("Error:: environment not terminated\n");
184: return -1;
185: }
186:
187: old = ub_envmatch(csName, e);
188: if (old)
189: break;
190: }
191:
192: /* Delete any existing definition */
193: if (old) {
194: if (!*++nxt)
195: *e = 0;
196: else
197: while (42) {
198: *e = *nxt++;
199: if (!*e && !*nxt)
200: break;
201: e++;
202: }
203: *++e = 0;
204: }
205:
206: if (csValue) {
207: /* Append new definition at the end */
208: for (e = env->env_data; *e || *(e + 1); e++);
209: if (e > env->env_data)
210: e++;
211: /* "name" + "=" + "val" +"\0\0" check u-boot-env size */
212: len = strlen(csName) + 2; /* add '=' for first arg, ' ' for all others */
213: len += strlen(csValue) + 1;
214: if (len > env->env_data + dlen - e) {
215: printf("Error:: Environment overflow!\n");
216: return -1;
217: }
218:
219: /* av pair */
220: while ((*e = *csName++))
221: e++;
222: *e = '=';
223: while ((*++e = *csValue++));
224:
225: /* end is marked with double '\0' */
226: *++e = 0;
227: }
228:
229: if (ub_flash_io(csSec, O_RDWR)) {
230: printf("Error:: Can't write environment to flash!\n");
231: return -1;
232: }
233:
234: return 0;
235: }
236:
237: int
238: ub_env(const char *csSec)
239: {
240: char *e, *nxt;
241: ssize_t dlen = 0;
242: const char *str;
243:
244: FTRACE(3);
245:
246: str = cfg_getAttribute(&cfg, csSec, "env_size");
247: if (!str) {
248: str = cfg_getAttribute(&cfg, csSec, "drive_size");
249: if (!str)
250: return -1;
251: dlen -= sizeof env->env_crc;
252: }
253: dlen += strtol(str, NULL, 0);
254: if (!dlen)
255: return -1;
256: else
257: dlen--;
258:
259: for (e = env->env_data; *e; e = nxt + 1) {
260: for (nxt = e; *nxt; nxt++)
261: if (nxt >= env->env_data + dlen) {
262: printf("Error:: environment not terminated\n");
263: return -1;
264: }
265:
266: printf("%s\n", e);
267: }
268:
269: return 0;
270: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>