Blame view
env/common.c
7.23 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
05706fddd Initial revision |
2 |
/* |
ea882baf9 New implementatio... |
3 |
* (C) Copyright 2000-2010 |
05706fddd Initial revision |
4 5 6 7 |
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Andreas Heppel <aheppel@sysgo.de> |
05706fddd Initial revision |
8 9 10 11 |
*/ #include <common.h> #include <command.h> |
3f989e7b0 env: Move env_rel... |
12 |
#include <env.h> |
f3998fdc4 env: Rename envir... |
13 |
#include <env_internal.h> |
8bef79bf3 common: Move sort... |
14 |
#include <sort.h> |
05706fddd Initial revision |
15 |
#include <linux/stddef.h> |
ea882baf9 New implementatio... |
16 17 |
#include <search.h> #include <errno.h> |
05706fddd Initial revision |
18 |
#include <malloc.h> |
3db711085 crc32: Use the cr... |
19 |
#include <u-boot/crc.h> |
05706fddd Initial revision |
20 |
|
d87080b72 GCC-4.x fixes: cl... |
21 |
DECLARE_GLOBAL_DATA_PTR; |
05706fddd Initial revision |
22 23 24 |
/************************************************************************ * Default settings to be used when no valid environment is found */ |
ddd8418f7 env: cosmetic: Co... |
25 |
#include <env_default.h> |
05706fddd Initial revision |
26 |
|
c5983592e env: add check/ap... |
27 |
struct hsearch_data env_htab = { |
2598090b7 env: Add environm... |
28 |
.change_ok = env_flags_validate, |
c5983592e env: add check/ap... |
29 |
}; |
2eb1573f0 hashtable: drop a... |
30 |
|
ec8a252cd env: Use getenv_y... |
31 32 33 34 |
/* * Read an environment variable as a boolean * Return -1 if variable does not exist (default to true) */ |
bfebc8c96 env: Rename geten... |
35 |
int env_get_yesno(const char *var) |
ec8a252cd env: Use getenv_y... |
36 |
{ |
00caae6d4 env: Rename geten... |
37 |
char *s = env_get(var); |
ec8a252cd env: Use getenv_y... |
38 39 40 41 42 43 |
if (s == NULL) return -1; return (*s == '1' || *s == 'y' || *s == 'Y' || *s == 't' || *s == 'T') ? 1 : 0; } |
267541f77 env: Add support ... |
44 45 46 |
/* * Look up the variable from the default environment */ |
723806cc5 env: Rename some ... |
47 |
char *env_get_default(const char *name) |
267541f77 env: Add support ... |
48 49 50 51 52 53 54 |
{ char *ret_val; unsigned long really_valid = gd->env_valid; unsigned long real_gd_flags = gd->flags; /* Pretend that the image is bad. */ gd->flags &= ~GD_FLG_ENV_READY; |
2d7cb5b42 env: Replace all ... |
55 |
gd->env_valid = ENV_INVALID; |
00caae6d4 env: Rename geten... |
56 |
ret_val = env_get(name); |
267541f77 env: Add support ... |
57 58 59 60 |
gd->env_valid = really_valid; gd->flags = real_gd_flags; return ret_val; } |
0ac7d722e env: Move get/set... |
61 |
void env_set_default(const char *s, int flags) |
5bb12dbd7 Remove code dupli... |
62 63 |
{ if (sizeof(default_environment) > ENV_SIZE) { |
ea882baf9 New implementatio... |
64 65 66 |
puts("*** Error - default environment is too large "); |
5bb12dbd7 Remove code dupli... |
67 68 |
return; } |
ea882baf9 New implementatio... |
69 |
if (s) { |
c5d548a9f env: common: acce... |
70 |
if ((flags & H_INTERACTIVE) == 0) { |
ea882baf9 New implementatio... |
71 |
printf("*** Warning - %s, " |
c5d548a9f env: common: acce... |
72 73 74 |
"using default environment ", s); |
ea882baf9 New implementatio... |
75 76 77 78 |
} else { puts(s); } } else { |
58ae9990c env: common: Make... |
79 80 |
debug("Using default environment "); |
ea882baf9 New implementatio... |
81 |
} |
2eb1573f0 hashtable: drop a... |
82 |
if (himport_r(&env_htab, (char *)default_environment, |
ecd1446fe Add option -r to ... |
83 |
sizeof(default_environment), '\0', flags, 0, |
c4e0057fa env: Refactor do_... |
84 |
0, NULL) == 0) |
6c90f6233 env: add the same... |
85 86 87 |
pr_err("## Error: Environment import failed: errno = %d ", errno); |
27aafe988 env: clean env_co... |
88 |
|
ea882baf9 New implementatio... |
89 |
gd->flags |= GD_FLG_ENV_READY; |
340b0e3bb env: Setup GD_FLG... |
90 |
gd->flags |= GD_FLG_ENV_DEFAULT; |
5bb12dbd7 Remove code dupli... |
91 |
} |
b64b7c3df env: make "env de... |
92 93 |
/* [re]set individual variables to their value in the default environment */ |
0b9d8a055 env: Move set_def... |
94 |
int env_set_default_vars(int nvars, char * const vars[], int flags) |
b64b7c3df env: make "env de... |
95 96 97 98 99 |
{ /* * Special use-case: import from default environment * (and use \0 as a separator) */ |
5a04264ec cmd: nvedit: set ... |
100 |
flags |= H_NOCLEAR; |
b64b7c3df env: make "env de... |
101 |
return himport_r(&env_htab, (const char *)default_environment, |
c4e0057fa env: Refactor do_... |
102 |
sizeof(default_environment), '\0', |
477f8116d cmd: nvedit: prop... |
103 |
flags, 0, nvars, vars); |
b64b7c3df env: make "env de... |
104 |
} |
ea882baf9 New implementatio... |
105 106 107 108 109 |
/* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. */ int env_import(const char *buf, int check) |
05706fddd Initial revision |
110 |
{ |
ea882baf9 New implementatio... |
111 |
env_t *ep = (env_t *)buf; |
05706fddd Initial revision |
112 |
|
ea882baf9 New implementatio... |
113 114 115 116 117 118 |
if (check) { uint32_t crc; memcpy(&crc, &ep->crc, sizeof(crc)); if (crc32(0, ep->data, ENV_SIZE) != crc) { |
0ac7d722e env: Move get/set... |
119 |
env_set_default("bad CRC", 0); |
49d04c589 env: common: Retu... |
120 |
return -ENOMSG; /* needed for env_load() */ |
ea882baf9 New implementatio... |
121 122 |
} } |
ecd1446fe Add option -r to ... |
123 |
if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0, |
c4e0057fa env: Refactor do_... |
124 |
0, NULL)) { |
ea882baf9 New implementatio... |
125 |
gd->flags |= GD_FLG_ENV_READY; |
42a1820bb env: make env_imp... |
126 |
return 0; |
ea882baf9 New implementatio... |
127 |
} |
05706fddd Initial revision |
128 |
|
9b643e312 treewide: replace... |
129 130 |
pr_err("Cannot import environment: errno = %d ", errno); |
ea882baf9 New implementatio... |
131 |
|
0ac7d722e env: Move get/set... |
132 |
env_set_default("import failed", 0); |
ea882baf9 New implementatio... |
133 |
|
42a1820bb env: make env_imp... |
134 |
return -EIO; |
ea882baf9 New implementatio... |
135 |
} |
76768f5f0 env: Add generic ... |
136 137 |
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT static unsigned char env_flags; |
31f044bd9 env: move more co... |
138 139 |
int env_import_redund(const char *buf1, int buf1_read_fail, const char *buf2, int buf2_read_fail) |
76768f5f0 env: Add generic ... |
140 141 142 143 144 145 |
{ int crc1_ok, crc2_ok; env_t *ep, *tmp_env1, *tmp_env2; tmp_env1 = (env_t *)buf1; tmp_env2 = (env_t *)buf2; |
31f044bd9 env: move more co... |
146 147 148 149 150 151 152 153 154 155 |
if (buf1_read_fail && buf2_read_fail) { puts("*** Error - No Valid Environment Area found "); } else if (buf1_read_fail || buf2_read_fail) { puts("*** Warning - some problems detected "); puts("reading environment; recovered successfully "); } if (buf1_read_fail && buf2_read_fail) { |
0ac7d722e env: Move get/set... |
156 |
env_set_default("bad env area", 0); |
31f044bd9 env: move more co... |
157 158 159 160 161 162 163 164 |
return -EIO; } else if (!buf1_read_fail && buf2_read_fail) { gd->env_valid = ENV_VALID; return env_import((char *)tmp_env1, 1); } else if (buf1_read_fail && !buf2_read_fail) { gd->env_valid = ENV_REDUND; return env_import((char *)tmp_env2, 1); } |
76768f5f0 env: Add generic ... |
165 166 167 168 169 170 |
crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc; crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc; if (!crc1_ok && !crc2_ok) { |
0ac7d722e env: Move get/set... |
171 |
env_set_default("bad CRC", 0); |
49d04c589 env: common: Retu... |
172 |
return -ENOMSG; /* needed for env_load() */ |
76768f5f0 env: Add generic ... |
173 |
} else if (crc1_ok && !crc2_ok) { |
2d7cb5b42 env: Replace all ... |
174 |
gd->env_valid = ENV_VALID; |
76768f5f0 env: Add generic ... |
175 |
} else if (!crc1_ok && crc2_ok) { |
2d7cb5b42 env: Replace all ... |
176 |
gd->env_valid = ENV_REDUND; |
76768f5f0 env: Add generic ... |
177 178 179 |
} else { /* both ok - check serial */ if (tmp_env1->flags == 255 && tmp_env2->flags == 0) |
2d7cb5b42 env: Replace all ... |
180 |
gd->env_valid = ENV_REDUND; |
76768f5f0 env: Add generic ... |
181 |
else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) |
2d7cb5b42 env: Replace all ... |
182 |
gd->env_valid = ENV_VALID; |
76768f5f0 env: Add generic ... |
183 |
else if (tmp_env1->flags > tmp_env2->flags) |
2d7cb5b42 env: Replace all ... |
184 |
gd->env_valid = ENV_VALID; |
76768f5f0 env: Add generic ... |
185 |
else if (tmp_env2->flags > tmp_env1->flags) |
2d7cb5b42 env: Replace all ... |
186 |
gd->env_valid = ENV_REDUND; |
76768f5f0 env: Add generic ... |
187 |
else /* flags are equal - almost impossible */ |
2d7cb5b42 env: Replace all ... |
188 |
gd->env_valid = ENV_VALID; |
76768f5f0 env: Add generic ... |
189 |
} |
2d7cb5b42 env: Replace all ... |
190 |
if (gd->env_valid == ENV_VALID) |
76768f5f0 env: Add generic ... |
191 192 193 194 195 196 197 198 |
ep = tmp_env1; else ep = tmp_env2; env_flags = ep->flags; return env_import((char *)ep, 0); } #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ |
fc0b5948e Various, accumula... |
199 |
/* Export the environment and generate CRC for it. */ |
7ce1526ed env: Add env_expo... |
200 201 202 203 204 205 206 207 |
int env_export(env_t *env_out) { char *res; ssize_t len; res = (char *)env_out->data; len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); if (len < 0) { |
9b643e312 treewide: replace... |
208 209 |
pr_err("Cannot export environment: errno = %d ", errno); |
7ce1526ed env: Add env_expo... |
210 211 |
return 1; } |
a4223b746 env: Implement su... |
212 |
|
7ce1526ed env: Add env_expo... |
213 |
env_out->crc = crc32(0, env_out->data, ENV_SIZE); |
76768f5f0 env: Add generic ... |
214 215 216 |
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT env_out->flags = ++env_flags; /* increase the serial */ #endif |
7ce1526ed env: Add env_expo... |
217 218 |
return 0; } |
27aafe988 env: clean env_co... |
219 |
void env_relocate(void) |
ea882baf9 New implementatio... |
220 |
{ |
2e5167cca Replace CONFIG_RE... |
221 |
#if defined(CONFIG_NEEDS_MANUAL_RELOC) |
60f7da1f4 env: fix cmd_env_... |
222 |
env_reloc(); |
7bcdf1957 env: Relocate env... |
223 |
env_fix_drivers(); |
d90fc9c3d Revert "env: solv... |
224 |
env_htab.change_ok += gd->reloc_off; |
60f7da1f4 env: fix cmd_env_... |
225 |
#endif |
2d7cb5b42 env: Replace all ... |
226 |
if (gd->env_valid == ENV_INVALID) { |
7ac2fe2da OMAP: networking ... |
227 228 |
#if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD) /* Environment not changable */ |
0ac7d722e env: Move get/set... |
229 |
env_set_default(NULL, 0); |
05706fddd Initial revision |
230 |
#else |
770605e4f bootstage: Replac... |
231 |
bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM); |
0ac7d722e env: Move get/set... |
232 |
env_set_default("bad CRC", 0); |
d259079d6 env: don't set to... |
233 |
#endif |
ea882baf9 New implementatio... |
234 |
} else { |
310fb14b2 env: Drop env_rel... |
235 |
env_load(); |
05706fddd Initial revision |
236 |
} |
05706fddd Initial revision |
237 |
} |
04a85b3b3 * Patches by Pant... |
238 |
|
03dcf17db common: command: ... |
239 240 241 |
#ifdef CONFIG_AUTO_COMPLETE int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf, bool dollar_comp) |
04a85b3b3 * Patches by Pant... |
242 |
{ |
dd2408cac env: Drop the ENT... |
243 |
struct env_entry *match; |
560d424b6 env: re-add suppo... |
244 |
int found, idx; |
04a85b3b3 * Patches by Pant... |
245 |
|
03dcf17db common: command: ... |
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
if (dollar_comp) { /* * When doing $ completion, the first character should * obviously be a '$'. */ if (var[0] != '$') return 0; var++; /* * The second one, if present, should be a '{', as some * configuration of the u-boot shell expand ${var} but not * $var. */ if (var[0] == '{') var++; else if (var[0] != '\0') return 0; } |
560d424b6 env: re-add suppo... |
266 |
idx = 0; |
04a85b3b3 * Patches by Pant... |
267 268 |
found = 0; cmdv[0] = NULL; |
03dcf17db common: command: ... |
269 |
|
560d424b6 env: re-add suppo... |
270 271 |
while ((idx = hmatch_r(var, idx, &match, &env_htab))) { int vallen = strlen(match->key) + 1; |
04a85b3b3 * Patches by Pant... |
272 |
|
03dcf17db common: command: ... |
273 274 |
if (found >= maxv - 2 || bufsz < vallen + (dollar_comp ? 3 : 0)) |
04a85b3b3 * Patches by Pant... |
275 |
break; |
560d424b6 env: re-add suppo... |
276 |
|
04a85b3b3 * Patches by Pant... |
277 |
cmdv[found++] = buf; |
03dcf17db common: command: ... |
278 279 280 281 282 283 284 |
/* Add the '${' prefix to each var when doing $ completion. */ if (dollar_comp) { strcpy(buf, "${"); buf += 2; bufsz -= 3; } |
560d424b6 env: re-add suppo... |
285 286 287 |
memcpy(buf, match->key, vallen); buf += vallen; bufsz -= vallen; |
03dcf17db common: command: ... |
288 289 290 291 292 293 294 295 296 297 298 299 |
if (dollar_comp) { /* * This one is a bit odd: vallen already contains the * '\0' character but we need to add the '}' suffix, * hence the buf - 1 here. strcpy() will add the '\0' * character just after '}'. buf is then incremented * to account for the extra '}' we just added. */ strcpy(buf - 1, "}"); buf++; } |
04a85b3b3 * Patches by Pant... |
300 |
} |
560d424b6 env: re-add suppo... |
301 302 303 |
qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar); if (idx) |
03dcf17db common: command: ... |
304 |
cmdv[found++] = dollar_comp ? "${...}" : "..."; |
27aafe988 env: clean env_co... |
305 |
|
04a85b3b3 * Patches by Pant... |
306 307 308 309 |
cmdv[found] = NULL; return found; } #endif |