xref: /openbmc/u-boot/lib/hashtable.c (revision 3600b461)
1 // SPDX-License-Identifier: LGPL-2.1+
2 /*
3  * This implementation is based on code from uClibc-0.9.30.3 but was
4  * modified and extended for use within U-Boot.
5  *
6  * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>
7  *
8  * Original license header:
9  *
10  * Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
11  * This file is part of the GNU C Library.
12  * Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1993.
13  */
14 
15 #include <errno.h>
16 #include <malloc.h>
17 
18 #ifdef USE_HOSTCC		/* HOST build */
19 # include <string.h>
20 # include <assert.h>
21 # include <ctype.h>
22 
23 # ifndef debug
24 #  ifdef DEBUG
25 #   define debug(fmt,args...)	printf(fmt ,##args)
26 #  else
27 #   define debug(fmt,args...)
28 #  endif
29 # endif
30 #else				/* U-Boot build */
31 # include <common.h>
32 # include <linux/string.h>
33 # include <linux/ctype.h>
34 #endif
35 
36 #ifndef	CONFIG_ENV_MIN_ENTRIES	/* minimum number of entries */
37 #define	CONFIG_ENV_MIN_ENTRIES 64
38 #endif
39 #ifndef	CONFIG_ENV_MAX_ENTRIES	/* maximum number of entries */
40 #define	CONFIG_ENV_MAX_ENTRIES 512
41 #endif
42 
43 #include <env_callback.h>
44 #include <env_flags.h>
45 #include <search.h>
46 #include <slre.h>
47 
48 /*
49  * [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
50  * [Knuth]	      The Art of Computer Programming, part 3 (6.4)
51  */
52 
53 /*
54  * The reentrant version has no static variables to maintain the state.
55  * Instead the interface of all functions is extended to take an argument
56  * which describes the current status.
57  */
58 
59 typedef struct _ENTRY {
60 	int used;
61 	ENTRY entry;
62 } _ENTRY;
63 
64 
65 static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep,
66 	int idx);
67 
68 /*
69  * hcreate()
70  */
71 
72 /*
73  * For the used double hash method the table size has to be a prime. To
74  * correct the user given table size we need a prime test.  This trivial
75  * algorithm is adequate because
76  * a)  the code is (most probably) called a few times per program run and
77  * b)  the number is small because the table must fit in the core
78  * */
79 static int isprime(unsigned int number)
80 {
81 	/* no even number will be passed */
82 	unsigned int div = 3;
83 
84 	while (div * div < number && number % div != 0)
85 		div += 2;
86 
87 	return number % div != 0;
88 }
89 
90 /*
91  * Before using the hash table we must allocate memory for it.
92  * Test for an existing table are done. We allocate one element
93  * more as the found prime number says. This is done for more effective
94  * indexing as explained in the comment for the hsearch function.
95  * The contents of the table is zeroed, especially the field used
96  * becomes zero.
97  */
98 
99 int hcreate_r(size_t nel, struct hsearch_data *htab)
100 {
101 	/* Test for correct arguments.  */
102 	if (htab == NULL) {
103 		__set_errno(EINVAL);
104 		return 0;
105 	}
106 
107 	/* There is still another table active. Return with error. */
108 	if (htab->table != NULL)
109 		return 0;
110 
111 	/* Change nel to the first prime number not smaller as nel. */
112 	nel |= 1;		/* make odd */
113 	while (!isprime(nel))
114 		nel += 2;
115 
116 	htab->size = nel;
117 	htab->filled = 0;
118 
119 	/* allocate memory and zero out */
120 	htab->table = (_ENTRY *) calloc(htab->size + 1, sizeof(_ENTRY));
121 	if (htab->table == NULL)
122 		return 0;
123 
124 	/* everything went alright */
125 	return 1;
126 }
127 
128 
129 /*
130  * hdestroy()
131  */
132 
133 /*
134  * After using the hash table it has to be destroyed. The used memory can
135  * be freed and the local static variable can be marked as not used.
136  */
137 
138 void hdestroy_r(struct hsearch_data *htab)
139 {
140 	int i;
141 
142 	/* Test for correct arguments.  */
143 	if (htab == NULL) {
144 		__set_errno(EINVAL);
145 		return;
146 	}
147 
148 	/* free used memory */
149 	for (i = 1; i <= htab->size; ++i) {
150 		if (htab->table[i].used > 0) {
151 			ENTRY *ep = &htab->table[i].entry;
152 
153 			free((void *)ep->key);
154 			free(ep->data);
155 		}
156 	}
157 	free(htab->table);
158 
159 	/* the sign for an existing table is an value != NULL in htable */
160 	htab->table = NULL;
161 }
162 
163 /*
164  * hsearch()
165  */
166 
167 /*
168  * This is the search function. It uses double hashing with open addressing.
169  * The argument item.key has to be a pointer to an zero terminated, most
170  * probably strings of chars. The function for generating a number of the
171  * strings is simple but fast. It can be replaced by a more complex function
172  * like ajw (see [Aho,Sethi,Ullman]) if the needs are shown.
173  *
174  * We use an trick to speed up the lookup. The table is created by hcreate
175  * with one more element available. This enables us to use the index zero
176  * special. This index will never be used because we store the first hash
177  * index in the field used where zero means not used. Every other value
178  * means used. The used field can be used as a first fast comparison for
179  * equality of the stored and the parameter value. This helps to prevent
180  * unnecessary expensive calls of strcmp.
181  *
182  * This implementation differs from the standard library version of
183  * this function in a number of ways:
184  *
185  * - While the standard version does not make any assumptions about
186  *   the type of the stored data objects at all, this implementation
187  *   works with NUL terminated strings only.
188  * - Instead of storing just pointers to the original objects, we
189  *   create local copies so the caller does not need to care about the
190  *   data any more.
191  * - The standard implementation does not provide a way to update an
192  *   existing entry.  This version will create a new entry or update an
193  *   existing one when both "action == ENTER" and "item.data != NULL".
194  * - Instead of returning 1 on success, we return the index into the
195  *   internal hash table, which is also guaranteed to be positive.
196  *   This allows us direct access to the found hash table slot for
197  *   example for functions like hdelete().
198  */
199 
200 int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
201 	     struct hsearch_data *htab)
202 {
203 	unsigned int idx;
204 	size_t key_len = strlen(match);
205 
206 	for (idx = last_idx + 1; idx < htab->size; ++idx) {
207 		if (htab->table[idx].used <= 0)
208 			continue;
209 		if (!strncmp(match, htab->table[idx].entry.key, key_len)) {
210 			*retval = &htab->table[idx].entry;
211 			return idx;
212 		}
213 	}
214 
215 	__set_errno(ESRCH);
216 	*retval = NULL;
217 	return 0;
218 }
219 
220 /*
221  * Compare an existing entry with the desired key, and overwrite if the action
222  * is ENTER.  This is simply a helper function for hsearch_r().
223  */
224 static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
225 	ENTRY **retval, struct hsearch_data *htab, int flag,
226 	unsigned int hval, unsigned int idx)
227 {
228 	if (htab->table[idx].used == hval
229 	    && strcmp(item.key, htab->table[idx].entry.key) == 0) {
230 		/* Overwrite existing value? */
231 		if ((action == ENTER) && (item.data != NULL)) {
232 			/* check for permission */
233 			if (htab->change_ok != NULL && htab->change_ok(
234 			    &htab->table[idx].entry, item.data,
235 			    env_op_overwrite, flag)) {
236 				debug("change_ok() rejected setting variable "
237 					"%s, skipping it!\n", item.key);
238 				__set_errno(EPERM);
239 				*retval = NULL;
240 				return 0;
241 			}
242 
243 			/* If there is a callback, call it */
244 			if (htab->table[idx].entry.callback &&
245 			    htab->table[idx].entry.callback(item.key,
246 			    item.data, env_op_overwrite, flag)) {
247 				debug("callback() rejected setting variable "
248 					"%s, skipping it!\n", item.key);
249 				__set_errno(EINVAL);
250 				*retval = NULL;
251 				return 0;
252 			}
253 
254 			free(htab->table[idx].entry.data);
255 			htab->table[idx].entry.data = strdup(item.data);
256 			if (!htab->table[idx].entry.data) {
257 				__set_errno(ENOMEM);
258 				*retval = NULL;
259 				return 0;
260 			}
261 		}
262 		/* return found entry */
263 		*retval = &htab->table[idx].entry;
264 		return idx;
265 	}
266 	/* keep searching */
267 	return -1;
268 }
269 
270 int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
271 	      struct hsearch_data *htab, int flag)
272 {
273 	unsigned int hval;
274 	unsigned int count;
275 	unsigned int len = strlen(item.key);
276 	unsigned int idx;
277 	unsigned int first_deleted = 0;
278 	int ret;
279 
280 	/* Compute an value for the given string. Perhaps use a better method. */
281 	hval = len;
282 	count = len;
283 	while (count-- > 0) {
284 		hval <<= 4;
285 		hval += item.key[count];
286 	}
287 
288 	/*
289 	 * First hash function:
290 	 * simply take the modul but prevent zero.
291 	 */
292 	hval %= htab->size;
293 	if (hval == 0)
294 		++hval;
295 
296 	/* The first index tried. */
297 	idx = hval;
298 
299 	if (htab->table[idx].used) {
300 		/*
301 		 * Further action might be required according to the
302 		 * action value.
303 		 */
304 		unsigned hval2;
305 
306 		if (htab->table[idx].used == -1
307 		    && !first_deleted)
308 			first_deleted = idx;
309 
310 		ret = _compare_and_overwrite_entry(item, action, retval, htab,
311 			flag, hval, idx);
312 		if (ret != -1)
313 			return ret;
314 
315 		/*
316 		 * Second hash function:
317 		 * as suggested in [Knuth]
318 		 */
319 		hval2 = 1 + hval % (htab->size - 2);
320 
321 		do {
322 			/*
323 			 * Because SIZE is prime this guarantees to
324 			 * step through all available indices.
325 			 */
326 			if (idx <= hval2)
327 				idx = htab->size + idx - hval2;
328 			else
329 				idx -= hval2;
330 
331 			/*
332 			 * If we visited all entries leave the loop
333 			 * unsuccessfully.
334 			 */
335 			if (idx == hval)
336 				break;
337 
338 			/* If entry is found use it. */
339 			ret = _compare_and_overwrite_entry(item, action, retval,
340 				htab, flag, hval, idx);
341 			if (ret != -1)
342 				return ret;
343 		}
344 		while (htab->table[idx].used);
345 	}
346 
347 	/* An empty bucket has been found. */
348 	if (action == ENTER) {
349 		/*
350 		 * If table is full and another entry should be
351 		 * entered return with error.
352 		 */
353 		if (htab->filled == htab->size) {
354 			__set_errno(ENOMEM);
355 			*retval = NULL;
356 			return 0;
357 		}
358 
359 		/*
360 		 * Create new entry;
361 		 * create copies of item.key and item.data
362 		 */
363 		if (first_deleted)
364 			idx = first_deleted;
365 
366 		htab->table[idx].used = hval;
367 		htab->table[idx].entry.key = strdup(item.key);
368 		htab->table[idx].entry.data = strdup(item.data);
369 		if (!htab->table[idx].entry.key ||
370 		    !htab->table[idx].entry.data) {
371 			__set_errno(ENOMEM);
372 			*retval = NULL;
373 			return 0;
374 		}
375 
376 		++htab->filled;
377 
378 		/* This is a new entry, so look up a possible callback */
379 		env_callback_init(&htab->table[idx].entry);
380 		/* Also look for flags */
381 		env_flags_init(&htab->table[idx].entry);
382 
383 		/* check for permission */
384 		if (htab->change_ok != NULL && htab->change_ok(
385 		    &htab->table[idx].entry, item.data, env_op_create, flag)) {
386 			debug("change_ok() rejected setting variable "
387 				"%s, skipping it!\n", item.key);
388 			_hdelete(item.key, htab, &htab->table[idx].entry, idx);
389 			__set_errno(EPERM);
390 			*retval = NULL;
391 			return 0;
392 		}
393 
394 		/* If there is a callback, call it */
395 		if (htab->table[idx].entry.callback &&
396 		    htab->table[idx].entry.callback(item.key, item.data,
397 		    env_op_create, flag)) {
398 			debug("callback() rejected setting variable "
399 				"%s, skipping it!\n", item.key);
400 			_hdelete(item.key, htab, &htab->table[idx].entry, idx);
401 			__set_errno(EINVAL);
402 			*retval = NULL;
403 			return 0;
404 		}
405 
406 		/* return new entry */
407 		*retval = &htab->table[idx].entry;
408 		return 1;
409 	}
410 
411 	__set_errno(ESRCH);
412 	*retval = NULL;
413 	return 0;
414 }
415 
416 
417 /*
418  * hdelete()
419  */
420 
421 /*
422  * The standard implementation of hsearch(3) does not provide any way
423  * to delete any entries from the hash table.  We extend the code to
424  * do that.
425  */
426 
427 static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep,
428 	int idx)
429 {
430 	/* free used ENTRY */
431 	debug("hdelete: DELETING key \"%s\"\n", key);
432 	free((void *)ep->key);
433 	free(ep->data);
434 	ep->callback = NULL;
435 	ep->flags = 0;
436 	htab->table[idx].used = -1;
437 
438 	--htab->filled;
439 }
440 
441 int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
442 {
443 	ENTRY e, *ep;
444 	int idx;
445 
446 	debug("hdelete: DELETE key \"%s\"\n", key);
447 
448 	e.key = (char *)key;
449 
450 	idx = hsearch_r(e, FIND, &ep, htab, 0);
451 	if (idx == 0) {
452 		__set_errno(ESRCH);
453 		return 0;	/* not found */
454 	}
455 
456 	/* Check for permission */
457 	if (htab->change_ok != NULL &&
458 	    htab->change_ok(ep, NULL, env_op_delete, flag)) {
459 		debug("change_ok() rejected deleting variable "
460 			"%s, skipping it!\n", key);
461 		__set_errno(EPERM);
462 		return 0;
463 	}
464 
465 	/* If there is a callback, call it */
466 	if (htab->table[idx].entry.callback &&
467 	    htab->table[idx].entry.callback(key, NULL, env_op_delete, flag)) {
468 		debug("callback() rejected deleting variable "
469 			"%s, skipping it!\n", key);
470 		__set_errno(EINVAL);
471 		return 0;
472 	}
473 
474 	_hdelete(key, htab, ep, idx);
475 
476 	return 1;
477 }
478 
479 #if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
480 /*
481  * hexport()
482  */
483 
484 /*
485  * Export the data stored in the hash table in linearized form.
486  *
487  * Entries are exported as "name=value" strings, separated by an
488  * arbitrary (non-NUL, of course) separator character. This allows to
489  * use this function both when formatting the U-Boot environment for
490  * external storage (using '\0' as separator), but also when using it
491  * for the "printenv" command to print all variables, simply by using
492  * as '\n" as separator. This can also be used for new features like
493  * exporting the environment data as text file, including the option
494  * for later re-import.
495  *
496  * The entries in the result list will be sorted by ascending key
497  * values.
498  *
499  * If the separator character is different from NUL, then any
500  * separator characters and backslash characters in the values will
501  * be escaped by a preceding backslash in output. This is needed for
502  * example to enable multi-line values, especially when the output
503  * shall later be parsed (for example, for re-import).
504  *
505  * There are several options how the result buffer is handled:
506  *
507  * *resp  size
508  * -----------
509  *  NULL    0	A string of sufficient length will be allocated.
510  *  NULL   >0	A string of the size given will be
511  *		allocated. An error will be returned if the size is
512  *		not sufficient.  Any unused bytes in the string will
513  *		be '\0'-padded.
514  * !NULL    0	The user-supplied buffer will be used. No length
515  *		checking will be performed, i. e. it is assumed that
516  *		the buffer size will always be big enough. DANGEROUS.
517  * !NULL   >0	The user-supplied buffer will be used. An error will
518  *		be returned if the size is not sufficient.  Any unused
519  *		bytes in the string will be '\0'-padded.
520  */
521 
522 static int cmpkey(const void *p1, const void *p2)
523 {
524 	ENTRY *e1 = *(ENTRY **) p1;
525 	ENTRY *e2 = *(ENTRY **) p2;
526 
527 	return (strcmp(e1->key, e2->key));
528 }
529 
530 static int match_string(int flag, const char *str, const char *pat, void *priv)
531 {
532 	switch (flag & H_MATCH_METHOD) {
533 	case H_MATCH_IDENT:
534 		if (strcmp(str, pat) == 0)
535 			return 1;
536 		break;
537 	case H_MATCH_SUBSTR:
538 		if (strstr(str, pat))
539 			return 1;
540 		break;
541 #ifdef CONFIG_REGEX
542 	case H_MATCH_REGEX:
543 		{
544 			struct slre *slrep = (struct slre *)priv;
545 
546 			if (slre_match(slrep, str, strlen(str), NULL))
547 				return 1;
548 		}
549 		break;
550 #endif
551 	default:
552 		printf("## ERROR: unsupported match method: 0x%02x\n",
553 			flag & H_MATCH_METHOD);
554 		break;
555 	}
556 	return 0;
557 }
558 
559 static int match_entry(ENTRY *ep, int flag,
560 		 int argc, char * const argv[])
561 {
562 	int arg;
563 	void *priv = NULL;
564 
565 	for (arg = 0; arg < argc; ++arg) {
566 #ifdef CONFIG_REGEX
567 		struct slre slre;
568 
569 		if (slre_compile(&slre, argv[arg]) == 0) {
570 			printf("Error compiling regex: %s\n", slre.err_str);
571 			return 0;
572 		}
573 
574 		priv = (void *)&slre;
575 #endif
576 		if (flag & H_MATCH_KEY) {
577 			if (match_string(flag, ep->key, argv[arg], priv))
578 				return 1;
579 		}
580 		if (flag & H_MATCH_DATA) {
581 			if (match_string(flag, ep->data, argv[arg], priv))
582 				return 1;
583 		}
584 	}
585 	return 0;
586 }
587 
588 ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
589 		 char **resp, size_t size,
590 		 int argc, char * const argv[])
591 {
592 	ENTRY *list[htab->size];
593 	char *res, *p;
594 	size_t totlen;
595 	int i, n;
596 
597 	/* Test for correct arguments.  */
598 	if ((resp == NULL) || (htab == NULL)) {
599 		__set_errno(EINVAL);
600 		return (-1);
601 	}
602 
603 	debug("EXPORT  table = %p, htab.size = %d, htab.filled = %d, size = %lu\n",
604 	      htab, htab->size, htab->filled, (ulong)size);
605 	/*
606 	 * Pass 1:
607 	 * search used entries,
608 	 * save addresses and compute total length
609 	 */
610 	for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
611 
612 		if (htab->table[i].used > 0) {
613 			ENTRY *ep = &htab->table[i].entry;
614 			int found = match_entry(ep, flag, argc, argv);
615 
616 			if ((argc > 0) && (found == 0))
617 				continue;
618 
619 			if ((flag & H_HIDE_DOT) && ep->key[0] == '.')
620 				continue;
621 
622 			list[n++] = ep;
623 
624 			totlen += strlen(ep->key);
625 
626 			if (sep == '\0') {
627 				totlen += strlen(ep->data);
628 			} else {	/* check if escapes are needed */
629 				char *s = ep->data;
630 
631 				while (*s) {
632 					++totlen;
633 					/* add room for needed escape chars */
634 					if ((*s == sep) || (*s == '\\'))
635 						++totlen;
636 					++s;
637 				}
638 			}
639 			totlen += 2;	/* for '=' and 'sep' char */
640 		}
641 	}
642 
643 #ifdef DEBUG
644 	/* Pass 1a: print unsorted list */
645 	printf("Unsorted: n=%d\n", n);
646 	for (i = 0; i < n; ++i) {
647 		printf("\t%3d: %p ==> %-10s => %s\n",
648 		       i, list[i], list[i]->key, list[i]->data);
649 	}
650 #endif
651 
652 	/* Sort list by keys */
653 	qsort(list, n, sizeof(ENTRY *), cmpkey);
654 
655 	/* Check if the user supplied buffer size is sufficient */
656 	if (size) {
657 		if (size < totlen + 1) {	/* provided buffer too small */
658 			printf("Env export buffer too small: %lu, but need %lu\n",
659 			       (ulong)size, (ulong)totlen + 1);
660 			__set_errno(ENOMEM);
661 			return (-1);
662 		}
663 	} else {
664 		size = totlen + 1;
665 	}
666 
667 	/* Check if the user provided a buffer */
668 	if (*resp) {
669 		/* yes; clear it */
670 		res = *resp;
671 		memset(res, '\0', size);
672 	} else {
673 		/* no, allocate and clear one */
674 		*resp = res = calloc(1, size);
675 		if (res == NULL) {
676 			__set_errno(ENOMEM);
677 			return (-1);
678 		}
679 	}
680 	/*
681 	 * Pass 2:
682 	 * export sorted list of result data
683 	 */
684 	for (i = 0, p = res; i < n; ++i) {
685 		const char *s;
686 
687 		s = list[i]->key;
688 		while (*s)
689 			*p++ = *s++;
690 		*p++ = '=';
691 
692 		s = list[i]->data;
693 
694 		while (*s) {
695 			if ((*s == sep) || (*s == '\\'))
696 				*p++ = '\\';	/* escape */
697 			*p++ = *s++;
698 		}
699 		*p++ = sep;
700 	}
701 	*p = '\0';		/* terminate result */
702 
703 	return size;
704 }
705 #endif
706 
707 
708 /*
709  * himport()
710  */
711 
712 /*
713  * Check whether variable 'name' is amongst vars[],
714  * and remove all instances by setting the pointer to NULL
715  */
716 static int drop_var_from_set(const char *name, int nvars, char * vars[])
717 {
718 	int i = 0;
719 	int res = 0;
720 
721 	/* No variables specified means process all of them */
722 	if (nvars == 0)
723 		return 1;
724 
725 	for (i = 0; i < nvars; i++) {
726 		if (vars[i] == NULL)
727 			continue;
728 		/* If we found it, delete all of them */
729 		if (!strcmp(name, vars[i])) {
730 			vars[i] = NULL;
731 			res = 1;
732 		}
733 	}
734 	if (!res)
735 		debug("Skipping non-listed variable %s\n", name);
736 
737 	return res;
738 }
739 
740 /*
741  * Import linearized data into hash table.
742  *
743  * This is the inverse function to hexport(): it takes a linear list
744  * of "name=value" pairs and creates hash table entries from it.
745  *
746  * Entries without "value", i. e. consisting of only "name" or
747  * "name=", will cause this entry to be deleted from the hash table.
748  *
749  * The "flag" argument can be used to control the behaviour: when the
750  * H_NOCLEAR bit is set, then an existing hash table will kept, i. e.
751  * new data will be added to an existing hash table; otherwise, if no
752  * vars are passed, old data will be discarded and a new hash table
753  * will be created. If vars are passed, passed vars that are not in
754  * the linear list of "name=value" pairs will be removed from the
755  * current hash table.
756  *
757  * The separator character for the "name=value" pairs can be selected,
758  * so we both support importing from externally stored environment
759  * data (separated by NUL characters) and from plain text files
760  * (entries separated by newline characters).
761  *
762  * To allow for nicely formatted text input, leading white space
763  * (sequences of SPACE and TAB chars) is ignored, and entries starting
764  * (after removal of any leading white space) with a '#' character are
765  * considered comments and ignored.
766  *
767  * [NOTE: this means that a variable name cannot start with a '#'
768  * character.]
769  *
770  * When using a non-NUL separator character, backslash is used as
771  * escape character in the value part, allowing for example for
772  * multi-line values.
773  *
774  * In theory, arbitrary separator characters can be used, but only
775  * '\0' and '\n' have really been tested.
776  */
777 
778 int himport_r(struct hsearch_data *htab,
779 		const char *env, size_t size, const char sep, int flag,
780 		int crlf_is_lf, int nvars, char * const vars[])
781 {
782 	char *data, *sp, *dp, *name, *value;
783 	char *localvars[nvars];
784 	int i;
785 
786 	/* Test for correct arguments.  */
787 	if (htab == NULL) {
788 		__set_errno(EINVAL);
789 		return 0;
790 	}
791 
792 	/* we allocate new space to make sure we can write to the array */
793 	if ((data = malloc(size + 1)) == NULL) {
794 		debug("himport_r: can't malloc %lu bytes\n", (ulong)size + 1);
795 		__set_errno(ENOMEM);
796 		return 0;
797 	}
798 	memcpy(data, env, size);
799 	data[size] = '\0';
800 	dp = data;
801 
802 	/* make a local copy of the list of variables */
803 	if (nvars)
804 		memcpy(localvars, vars, sizeof(vars[0]) * nvars);
805 
806 	if ((flag & H_NOCLEAR) == 0 && !nvars) {
807 		/* Destroy old hash table if one exists */
808 		debug("Destroy Hash Table: %p table = %p\n", htab,
809 		       htab->table);
810 		if (htab->table)
811 			hdestroy_r(htab);
812 	}
813 
814 	/*
815 	 * Create new hash table (if needed).  The computation of the hash
816 	 * table size is based on heuristics: in a sample of some 70+
817 	 * existing systems we found an average size of 39+ bytes per entry
818 	 * in the environment (for the whole key=value pair). Assuming a
819 	 * size of 8 per entry (= safety factor of ~5) should provide enough
820 	 * safety margin for any existing environment definitions and still
821 	 * allow for more than enough dynamic additions. Note that the
822 	 * "size" argument is supposed to give the maximum environment size
823 	 * (CONFIG_ENV_SIZE).  This heuristics will result in
824 	 * unreasonably large numbers (and thus memory footprint) for
825 	 * big flash environments (>8,000 entries for 64 KB
826 	 * environment size), so we clip it to a reasonable value.
827 	 * On the other hand we need to add some more entries for free
828 	 * space when importing very small buffers. Both boundaries can
829 	 * be overwritten in the board config file if needed.
830 	 */
831 
832 	if (!htab->table) {
833 		int nent = CONFIG_ENV_MIN_ENTRIES + size / 8;
834 
835 		if (nent > CONFIG_ENV_MAX_ENTRIES)
836 			nent = CONFIG_ENV_MAX_ENTRIES;
837 
838 		debug("Create Hash Table: N=%d\n", nent);
839 
840 		if (hcreate_r(nent, htab) == 0) {
841 			free(data);
842 			return 0;
843 		}
844 	}
845 
846 	if (!size) {
847 		free(data);
848 		return 1;		/* everything OK */
849 	}
850 	if(crlf_is_lf) {
851 		/* Remove Carriage Returns in front of Line Feeds */
852 		unsigned ignored_crs = 0;
853 		for(;dp < data + size && *dp; ++dp) {
854 			if(*dp == '\r' &&
855 			   dp < data + size - 1 && *(dp+1) == '\n')
856 				++ignored_crs;
857 			else
858 				*(dp-ignored_crs) = *dp;
859 		}
860 		size -= ignored_crs;
861 		dp = data;
862 	}
863 	/* Parse environment; allow for '\0' and 'sep' as separators */
864 	do {
865 		ENTRY e, *rv;
866 
867 		/* skip leading white space */
868 		while (isblank(*dp))
869 			++dp;
870 
871 		/* skip comment lines */
872 		if (*dp == '#') {
873 			while (*dp && (*dp != sep))
874 				++dp;
875 			++dp;
876 			continue;
877 		}
878 
879 		/* parse name */
880 		for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp)
881 			;
882 
883 		/* deal with "name" and "name=" entries (delete var) */
884 		if (*dp == '\0' || *(dp + 1) == '\0' ||
885 		    *dp == sep || *(dp + 1) == sep) {
886 			if (*dp == '=')
887 				*dp++ = '\0';
888 			*dp++ = '\0';	/* terminate name */
889 
890 			debug("DELETE CANDIDATE: \"%s\"\n", name);
891 			if (!drop_var_from_set(name, nvars, localvars))
892 				continue;
893 
894 			if (hdelete_r(name, htab, flag) == 0)
895 				debug("DELETE ERROR ##############################\n");
896 
897 			continue;
898 		}
899 		*dp++ = '\0';	/* terminate name */
900 
901 		/* parse value; deal with escapes */
902 		for (value = sp = dp; *dp && (*dp != sep); ++dp) {
903 			if ((*dp == '\\') && *(dp + 1))
904 				++dp;
905 			*sp++ = *dp;
906 		}
907 		*sp++ = '\0';	/* terminate value */
908 		++dp;
909 
910 		if (*name == 0) {
911 			debug("INSERT: unable to use an empty key\n");
912 			__set_errno(EINVAL);
913 			free(data);
914 			return 0;
915 		}
916 
917 		/* Skip variables which are not supposed to be processed */
918 		if (!drop_var_from_set(name, nvars, localvars))
919 			continue;
920 
921 		/* enter into hash table */
922 		e.key = name;
923 		e.data = value;
924 
925 		hsearch_r(e, ENTER, &rv, htab, flag);
926 		if (rv == NULL)
927 			printf("himport_r: can't insert \"%s=%s\" into hash table\n",
928 				name, value);
929 
930 		debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n",
931 			htab, htab->filled, htab->size,
932 			rv, name, value);
933 	} while ((dp < data + size) && *dp);	/* size check needed for text */
934 						/* without '\0' termination */
935 	debug("INSERT: free(data = %p)\n", data);
936 	free(data);
937 
938 	if (flag & H_NOCLEAR)
939 		goto end;
940 
941 	/* process variables which were not considered */
942 	for (i = 0; i < nvars; i++) {
943 		if (localvars[i] == NULL)
944 			continue;
945 		/*
946 		 * All variables which were not deleted from the variable list
947 		 * were not present in the imported env
948 		 * This could mean two things:
949 		 * a) if the variable was present in current env, we delete it
950 		 * b) if the variable was not present in current env, we notify
951 		 *    it might be a typo
952 		 */
953 		if (hdelete_r(localvars[i], htab, flag) == 0)
954 			printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]);
955 		else
956 			printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]);
957 	}
958 
959 end:
960 	debug("INSERT: done\n");
961 	return 1;		/* everything OK */
962 }
963 
964 /*
965  * hwalk_r()
966  */
967 
968 /*
969  * Walk all of the entries in the hash, calling the callback for each one.
970  * this allows some generic operation to be performed on each element.
971  */
972 int hwalk_r(struct hsearch_data *htab, int (*callback)(ENTRY *))
973 {
974 	int i;
975 	int retval;
976 
977 	for (i = 1; i <= htab->size; ++i) {
978 		if (htab->table[i].used > 0) {
979 			retval = callback(&htab->table[i].entry);
980 			if (retval)
981 				return retval;
982 		}
983 	}
984 
985 	return 0;
986 }
987