Blame view

common/env_common.c 4.58 KB
05706fddd   wdenk   Initial revision
1
  /*
ea882baf9   Wolfgang Denk   New implementatio...
2
   * (C) Copyright 2000-2010
05706fddd   wdenk   Initial revision
3
4
5
6
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
   * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   * Andreas Heppel <aheppel@sysgo.de>
ea882baf9   Wolfgang Denk   New implementatio...
7
   *
3765b3e7b   Wolfgang Denk   Coding Style clea...
8
   * SPDX-License-Identifier:	GPL-2.0+
05706fddd   wdenk   Initial revision
9
10
11
12
13
   */
  
  #include <common.h>
  #include <command.h>
  #include <environment.h>
05706fddd   wdenk   Initial revision
14
  #include <linux/stddef.h>
ea882baf9   Wolfgang Denk   New implementatio...
15
16
  #include <search.h>
  #include <errno.h>
05706fddd   wdenk   Initial revision
17
  #include <malloc.h>
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
18
  DECLARE_GLOBAL_DATA_PTR;
05706fddd   wdenk   Initial revision
19
20
21
  /************************************************************************
   * Default settings to be used when no valid environment is found
   */
ddd8418f7   Joe Hershberger   env: cosmetic: Co...
22
  #include <env_default.h>
05706fddd   wdenk   Initial revision
23

c5983592e   Gerlando Falauto   env: add check/ap...
24
  struct hsearch_data env_htab = {
2598090b7   Joe Hershberger   env: Add environm...
25
  	.change_ok = env_flags_validate,
c5983592e   Gerlando Falauto   env: add check/ap...
26
  };
2eb1573f0   Mike Frysinger   hashtable: drop a...
27

bf95df44f   Igor Grinberg   env: factor out t...
28
29
30
31
32
33
  static uchar __env_get_char_spec(int index)
  {
  	return *((uchar *)(gd->env_addr + index));
  }
  uchar env_get_char_spec(int)
  	__attribute__((weak, alias("__env_get_char_spec")));
27aafe988   Igor Grinberg   env: clean env_co...
34
  static uchar env_get_char_init(int index)
05706fddd   wdenk   Initial revision
35
  {
05706fddd   wdenk   Initial revision
36
37
  	/* if crc was bad, use the default environment */
  	if (gd->env_valid)
27aafe988   Igor Grinberg   env: clean env_co...
38
  		return env_get_char_spec(index);
ea882baf9   Wolfgang Denk   New implementatio...
39
  	else
27aafe988   Igor Grinberg   env: clean env_co...
40
  		return default_environment[index];
05706fddd   wdenk   Initial revision
41
  }
27aafe988   Igor Grinberg   env: clean env_co...
42
  uchar env_get_char_memory(int index)
05706fddd   wdenk   Initial revision
43
  {
ea882baf9   Wolfgang Denk   New implementatio...
44
  	return *env_get_addr(index);
05706fddd   wdenk   Initial revision
45
  }
27aafe988   Igor Grinberg   env: clean env_co...
46
  uchar env_get_char(int index)
b502611b5   Joakim Tjernlund   Change env_get_ch...
47
  {
b502611b5   Joakim Tjernlund   Change env_get_ch...
48
49
  	/* if relocated to RAM */
  	if (gd->flags & GD_FLG_RELOC)
27aafe988   Igor Grinberg   env: clean env_co...
50
  		return env_get_char_memory(index);
b502611b5   Joakim Tjernlund   Change env_get_ch...
51
  	else
27aafe988   Igor Grinberg   env: clean env_co...
52
  		return env_get_char_init(index);
b502611b5   Joakim Tjernlund   Change env_get_ch...
53
  }
27aafe988   Igor Grinberg   env: clean env_co...
54
  const uchar *env_get_addr(int index)
05706fddd   wdenk   Initial revision
55
  {
ea882baf9   Wolfgang Denk   New implementatio...
56
57
58
59
  	if (gd->env_valid)
  		return (uchar *)(gd->env_addr + index);
  	else
  		return &default_environment[index];
05706fddd   wdenk   Initial revision
60
  }
ec8a252cd   Joe Hershberger   env: Use getenv_y...
61
62
63
64
65
66
67
68
69
70
71
72
73
  /*
   * Read an environment variable as a boolean
   * Return -1 if variable does not exist (default to true)
   */
  int getenv_yesno(const char *var)
  {
  	char *s = getenv(var);
  
  	if (s == NULL)
  		return -1;
  	return (*s == '1' || *s == 'y' || *s == 'Y' || *s == 't' || *s == 'T') ?
  		1 : 0;
  }
267541f77   Joe Hershberger   env: Add support ...
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  /*
   * Look up the variable from the default environment
   */
  char *getenv_default(const char *name)
  {
  	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;
  	gd->env_valid = 0;
  	ret_val = getenv(name);
  	gd->env_valid = really_valid;
  	gd->flags = real_gd_flags;
  	return ret_val;
  }
ea882baf9   Wolfgang Denk   New implementatio...
91
  void set_default_env(const char *s)
5bb12dbd7   Harald Welte   Remove code dupli...
92
  {
c4e0057fa   Joe Hershberger   env: Refactor do_...
93
  	int flags = 0;
5bb12dbd7   Harald Welte   Remove code dupli...
94
  	if (sizeof(default_environment) > ENV_SIZE) {
ea882baf9   Wolfgang Denk   New implementatio...
95
96
97
  		puts("*** Error - default environment is too large
  
  ");
5bb12dbd7   Harald Welte   Remove code dupli...
98
99
  		return;
  	}
ea882baf9   Wolfgang Denk   New implementatio...
100
101
102
103
104
105
  	if (s) {
  		if (*s == '!') {
  			printf("*** Warning - %s, "
  				"using default environment
  
  ",
27aafe988   Igor Grinberg   env: clean env_co...
106
  				s + 1);
ea882baf9   Wolfgang Denk   New implementatio...
107
  		} else {
c4e0057fa   Joe Hershberger   env: Refactor do_...
108
  			flags = H_INTERACTIVE;
ea882baf9   Wolfgang Denk   New implementatio...
109
110
111
112
113
114
115
  			puts(s);
  		}
  	} else {
  		puts("Using default environment
  
  ");
  	}
2eb1573f0   Mike Frysinger   hashtable: drop a...
116
  	if (himport_r(&env_htab, (char *)default_environment,
c4e0057fa   Joe Hershberger   env: Refactor do_...
117
118
  			sizeof(default_environment), '\0', flags,
  			0, NULL) == 0)
ea882baf9   Wolfgang Denk   New implementatio...
119
120
  		error("Environment import failed: errno = %d
  ", errno);
27aafe988   Igor Grinberg   env: clean env_co...
121

ea882baf9   Wolfgang Denk   New implementatio...
122
  	gd->flags |= GD_FLG_ENV_READY;
5bb12dbd7   Harald Welte   Remove code dupli...
123
  }
b64b7c3df   Gerlando Falauto   env: make "env de...
124
125
126
127
128
129
130
131
132
  
  /* [re]set individual variables to their value in the default environment */
  int set_default_vars(int nvars, char * const vars[])
  {
  	/*
  	 * Special use-case: import from default environment
  	 * (and use \0 as a separator)
  	 */
  	return himport_r(&env_htab, (const char *)default_environment,
c4e0057fa   Joe Hershberger   env: Refactor do_...
133
134
  				sizeof(default_environment), '\0',
  				H_NOCLEAR | H_INTERACTIVE, nvars, vars);
b64b7c3df   Gerlando Falauto   env: make "env de...
135
  }
ea882baf9   Wolfgang Denk   New implementatio...
136
137
138
139
140
  /*
   * 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   wdenk   Initial revision
141
  {
ea882baf9   Wolfgang Denk   New implementatio...
142
  	env_t *ep = (env_t *)buf;
05706fddd   wdenk   Initial revision
143

ea882baf9   Wolfgang Denk   New implementatio...
144
145
146
147
148
149
150
151
152
153
  	if (check) {
  		uint32_t crc;
  
  		memcpy(&crc, &ep->crc, sizeof(crc));
  
  		if (crc32(0, ep->data, ENV_SIZE) != crc) {
  			set_default_env("!bad CRC");
  			return 0;
  		}
  	}
348b1f1c6   Gerlando Falauto   env: make himport...
154
  	if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0,
c4e0057fa   Joe Hershberger   env: Refactor do_...
155
  			0, NULL)) {
ea882baf9   Wolfgang Denk   New implementatio...
156
157
158
  		gd->flags |= GD_FLG_ENV_READY;
  		return 1;
  	}
05706fddd   wdenk   Initial revision
159

ea882baf9   Wolfgang Denk   New implementatio...
160
161
162
163
164
165
166
  	error("Cannot import environment: errno = %d
  ", errno);
  
  	set_default_env("!import failed");
  
  	return 0;
  }
27aafe988   Igor Grinberg   env: clean env_co...
167
  void env_relocate(void)
ea882baf9   Wolfgang Denk   New implementatio...
168
  {
2e5167cca   Wolfgang Denk   Replace CONFIG_RE...
169
  #if defined(CONFIG_NEEDS_MANUAL_RELOC)
60f7da1f4   Heiko Schocher   env: fix cmd_env_...
170
  	env_reloc();
7afcf3a55   Joe Hershberger   env: Refactor app...
171
  	env_htab.change_ok += gd->reloc_off;
60f7da1f4   Heiko Schocher   env: fix cmd_env_...
172
  #endif
05706fddd   wdenk   Initial revision
173
  	if (gd->env_valid == 0) {
7ac2fe2da   Ilya Yanok   OMAP: networking ...
174
175
  #if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD)
  		/* Environment not changable */
ea882baf9   Wolfgang Denk   New implementatio...
176
  		set_default_env(NULL);
05706fddd   wdenk   Initial revision
177
  #else
770605e4f   Simon Glass   bootstage: Replac...
178
  		bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM);
ea882baf9   Wolfgang Denk   New implementatio...
179
  		set_default_env("!bad CRC");
d259079d6   Lei Wen   env: don't set to...
180
  #endif
ea882baf9   Wolfgang Denk   New implementatio...
181
  	} else {
27aafe988   Igor Grinberg   env: clean env_co...
182
  		env_relocate_spec();
05706fddd   wdenk   Initial revision
183
  	}
05706fddd   wdenk   Initial revision
184
  }
04a85b3b3   wdenk   * Patches by Pant...
185

7ac2fe2da   Ilya Yanok   OMAP: networking ...
186
  #if defined(CONFIG_AUTO_COMPLETE) && !defined(CONFIG_SPL_BUILD)
04a85b3b3   wdenk   * Patches by Pant...
187
188
  int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
  {
560d424b6   Mike Frysinger   env: re-add suppo...
189
190
  	ENTRY *match;
  	int found, idx;
04a85b3b3   wdenk   * Patches by Pant...
191

560d424b6   Mike Frysinger   env: re-add suppo...
192
  	idx = 0;
04a85b3b3   wdenk   * Patches by Pant...
193
194
  	found = 0;
  	cmdv[0] = NULL;
560d424b6   Mike Frysinger   env: re-add suppo...
195
196
  	while ((idx = hmatch_r(var, idx, &match, &env_htab))) {
  		int vallen = strlen(match->key) + 1;
04a85b3b3   wdenk   * Patches by Pant...
197

560d424b6   Mike Frysinger   env: re-add suppo...
198
  		if (found >= maxv - 2 || bufsz < vallen)
04a85b3b3   wdenk   * Patches by Pant...
199
  			break;
560d424b6   Mike Frysinger   env: re-add suppo...
200

04a85b3b3   wdenk   * Patches by Pant...
201
  		cmdv[found++] = buf;
560d424b6   Mike Frysinger   env: re-add suppo...
202
203
204
  		memcpy(buf, match->key, vallen);
  		buf += vallen;
  		bufsz -= vallen;
04a85b3b3   wdenk   * Patches by Pant...
205
  	}
560d424b6   Mike Frysinger   env: re-add suppo...
206
207
208
209
  	qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar);
  
  	if (idx)
  		cmdv[found++] = "...";
27aafe988   Igor Grinberg   env: clean env_co...
210

04a85b3b3   wdenk   * Patches by Pant...
211
212
213
214
  	cmdv[found] = NULL;
  	return found;
  }
  #endif