xref: /openbmc/u-boot/lib/hashtable.c (revision 8ee59472)
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 			struct cap caps[slrep->num_caps + 2];
546 
547 			if (slre_match(slrep, str, strlen(str), caps))
548 				return 1;
549 		}
550 		break;
551 #endif
552 	default:
553 		printf("## ERROR: unsupported match method: 0x%02x\n",
554 			flag & H_MATCH_METHOD);
555 		break;
556 	}
557 	return 0;
558 }
559 
560 static int match_entry(ENTRY *ep, int flag,
561 		 int argc, char * const argv[])
562 {
563 	int arg;
564 	void *priv = NULL;
565 
566 	for (arg = 0; arg < argc; ++arg) {
567 #ifdef CONFIG_REGEX
568 		struct slre slre;
569 
570 		if (slre_compile(&slre, argv[arg]) == 0) {
571 			printf("Error compiling regex: %s\n", slre.err_str);
572 			return 0;
573 		}
574 
575 		priv = (void *)&slre;
576 #endif
577 		if (flag & H_MATCH_KEY) {
578 			if (match_string(flag, ep->key, argv[arg], priv))
579 				return 1;
580 		}
581 		if (flag & H_MATCH_DATA) {
582 			if (match_string(flag, ep->data, argv[arg], priv))
583 				return 1;
584 		}
585 	}
586 	return 0;
587 }
588 
589 ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
590 		 char **resp, size_t size,
591 		 int argc, char * const argv[])
592 {
593 	ENTRY *list[htab->size];
594 	char *res, *p;
595 	size_t totlen;
596 	int i, n;
597 
598 	/* Test for correct arguments.  */
599 	if ((resp == NULL) || (htab == NULL)) {
600 		__set_errno(EINVAL);
601 		return (-1);
602 	}
603 
604 	debug("EXPORT  table = %p, htab.size = %d, htab.filled = %d, size = %lu\n",
605 	      htab, htab->size, htab->filled, (ulong)size);
606 	/*
607 	 * Pass 1:
608 	 * search used entries,
609 	 * save addresses and compute total length
610 	 */
611 	for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
612 
613 		if (htab->table[i].used > 0) {
614 			ENTRY *ep = &htab->table[i].entry;
615 			int found = match_entry(ep, flag, argc, argv);
616 
617 			if ((argc > 0) && (found == 0))
618 				continue;
619 
620 			if ((flag & H_HIDE_DOT) && ep->key[0] == '.')
621 				continue;
622 
623 			list[n++] = ep;
624 
625 			totlen += strlen(ep->key) + 2;
626 
627 			if (sep == '\0') {
628 				totlen += strlen(ep->data);
629 			} else {	/* check if escapes are needed */
630 				char *s = ep->data;
631 
632 				while (*s) {
633 					++totlen;
634 					/* add room for needed escape chars */
635 					if ((*s == sep) || (*s == '\\'))
636 						++totlen;
637 					++s;
638 				}
639 			}
640 			totlen += 2;	/* for '=' and 'sep' char */
641 		}
642 	}
643 
644 #ifdef DEBUG
645 	/* Pass 1a: print unsorted list */
646 	printf("Unsorted: n=%d\n", n);
647 	for (i = 0; i < n; ++i) {
648 		printf("\t%3d: %p ==> %-10s => %s\n",
649 		       i, list[i], list[i]->key, list[i]->data);
650 	}
651 #endif
652 
653 	/* Sort list by keys */
654 	qsort(list, n, sizeof(ENTRY *), cmpkey);
655 
656 	/* Check if the user supplied buffer size is sufficient */
657 	if (size) {
658 		if (size < totlen + 1) {	/* provided buffer too small */
659 			printf("Env export buffer too small: %lu, but need %lu\n",
660 			       (ulong)size, (ulong)totlen + 1);
661 			__set_errno(ENOMEM);
662 			return (-1);
663 		}
664 	} else {
665 		size = totlen + 1;
666 	}
667 
668 	/* Check if the user provided a buffer */
669 	if (*resp) {
670 		/* yes; clear it */
671 		res = *resp;
672 		memset(res, '\0', size);
673 	} else {
674 		/* no, allocate and clear one */
675 		*resp = res = calloc(1, size);
676 		if (res == NULL) {
677 			__set_errno(ENOMEM);
678 			return (-1);
679 		}
680 	}
681 	/*
682 	 * Pass 2:
683 	 * export sorted list of result data
684 	 */
685 	for (i = 0, p = res; i < n; ++i) {
686 		const char *s;
687 
688 		s = list[i]->key;
689 		while (*s)
690 			*p++ = *s++;
691 		*p++ = '=';
692 
693 		s = list[i]->data;
694 
695 		while (*s) {
696 			if ((*s == sep) || (*s == '\\'))
697 				*p++ = '\\';	/* escape */
698 			*p++ = *s++;
699 		}
700 		*p++ = sep;
701 	}
702 	*p = '\0';		/* terminate result */
703 
704 	return size;
705 }
706 #endif
707 
708 
709 /*
710  * himport()
711  */
712 
713 /*
714  * Check whether variable 'name' is amongst vars[],
715  * and remove all instances by setting the pointer to NULL
716  */
717 static int drop_var_from_set(const char *name, int nvars, char * vars[])
718 {
719 	int i = 0;
720 	int res = 0;
721 
722 	/* No variables specified means process all of them */
723 	if (nvars == 0)
724 		return 1;
725 
726 	for (i = 0; i < nvars; i++) {
727 		if (vars[i] == NULL)
728 			continue;
729 		/* If we found it, delete all of them */
730 		if (!strcmp(name, vars[i])) {
731 			vars[i] = NULL;
732 			res = 1;
733 		}
734 	}
735 	if (!res)
736 		debug("Skipping non-listed variable %s\n", name);
737 
738 	return res;
739 }
740 
741 /*
742  * Import linearized data into hash table.
743  *
744  * This is the inverse function to hexport(): it takes a linear list
745  * of "name=value" pairs and creates hash table entries from it.
746  *
747  * Entries without "value", i. e. consisting of only "name" or
748  * "name=", will cause this entry to be deleted from the hash table.
749  *
750  * The "flag" argument can be used to control the behaviour: when the
751  * H_NOCLEAR bit is set, then an existing hash table will kept, i. e.
752  * new data will be added to an existing hash table; otherwise, old
753  * data will be discarded and a new hash table will be created.
754  *
755  * The separator character for the "name=value" pairs can be selected,
756  * so we both support importing from externally stored environment
757  * data (separated by NUL characters) and from plain text files
758  * (entries separated by newline characters).
759  *
760  * To allow for nicely formatted text input, leading white space
761  * (sequences of SPACE and TAB chars) is ignored, and entries starting
762  * (after removal of any leading white space) with a '#' character are
763  * considered comments and ignored.
764  *
765  * [NOTE: this means that a variable name cannot start with a '#'
766  * character.]
767  *
768  * When using a non-NUL separator character, backslash is used as
769  * escape character in the value part, allowing for example for
770  * multi-line values.
771  *
772  * In theory, arbitrary separator characters can be used, but only
773  * '\0' and '\n' have really been tested.
774  */
775 
776 int himport_r(struct hsearch_data *htab,
777 		const char *env, size_t size, const char sep, int flag,
778 		int crlf_is_lf, int nvars, char * const vars[])
779 {
780 	char *data, *sp, *dp, *name, *value;
781 	char *localvars[nvars];
782 	int i;
783 
784 	/* Test for correct arguments.  */
785 	if (htab == NULL) {
786 		__set_errno(EINVAL);
787 		return 0;
788 	}
789 
790 	/* we allocate new space to make sure we can write to the array */
791 	if ((data = malloc(size + 1)) == NULL) {
792 		debug("himport_r: can't malloc %lu bytes\n", (ulong)size + 1);
793 		__set_errno(ENOMEM);
794 		return 0;
795 	}
796 	memcpy(data, env, size);
797 	data[size] = '\0';
798 	dp = data;
799 
800 	/* make a local copy of the list of variables */
801 	if (nvars)
802 		memcpy(localvars, vars, sizeof(vars[0]) * nvars);
803 
804 	if ((flag & H_NOCLEAR) == 0) {
805 		/* Destroy old hash table if one exists */
806 		debug("Destroy Hash Table: %p table = %p\n", htab,
807 		       htab->table);
808 		if (htab->table)
809 			hdestroy_r(htab);
810 	}
811 
812 	/*
813 	 * Create new hash table (if needed).  The computation of the hash
814 	 * table size is based on heuristics: in a sample of some 70+
815 	 * existing systems we found an average size of 39+ bytes per entry
816 	 * in the environment (for the whole key=value pair). Assuming a
817 	 * size of 8 per entry (= safety factor of ~5) should provide enough
818 	 * safety margin for any existing environment definitions and still
819 	 * allow for more than enough dynamic additions. Note that the
820 	 * "size" argument is supposed to give the maximum environment size
821 	 * (CONFIG_ENV_SIZE).  This heuristics will result in
822 	 * unreasonably large numbers (and thus memory footprint) for
823 	 * big flash environments (>8,000 entries for 64 KB
824 	 * environment size), so we clip it to a reasonable value.
825 	 * On the other hand we need to add some more entries for free
826 	 * space when importing very small buffers. Both boundaries can
827 	 * be overwritten in the board config file if needed.
828 	 */
829 
830 	if (!htab->table) {
831 		int nent = CONFIG_ENV_MIN_ENTRIES + size / 8;
832 
833 		if (nent > CONFIG_ENV_MAX_ENTRIES)
834 			nent = CONFIG_ENV_MAX_ENTRIES;
835 
836 		debug("Create Hash Table: N=%d\n", nent);
837 
838 		if (hcreate_r(nent, htab) == 0) {
839 			free(data);
840 			return 0;
841 		}
842 	}
843 
844 	if (!size) {
845 		free(data);
846 		return 1;		/* everything OK */
847 	}
848 	if(crlf_is_lf) {
849 		/* Remove Carriage Returns in front of Line Feeds */
850 		unsigned ignored_crs = 0;
851 		for(;dp < data + size && *dp; ++dp) {
852 			if(*dp == '\r' &&
853 			   dp < data + size - 1 && *(dp+1) == '\n')
854 				++ignored_crs;
855 			else
856 				*(dp-ignored_crs) = *dp;
857 		}
858 		size -= ignored_crs;
859 		dp = data;
860 	}
861 	/* Parse environment; allow for '\0' and 'sep' as separators */
862 	do {
863 		ENTRY e, *rv;
864 
865 		/* skip leading white space */
866 		while (isblank(*dp))
867 			++dp;
868 
869 		/* skip comment lines */
870 		if (*dp == '#') {
871 			while (*dp && (*dp != sep))
872 				++dp;
873 			++dp;
874 			continue;
875 		}
876 
877 		/* parse name */
878 		for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp)
879 			;
880 
881 		/* deal with "name" and "name=" entries (delete var) */
882 		if (*dp == '\0' || *(dp + 1) == '\0' ||
883 		    *dp == sep || *(dp + 1) == sep) {
884 			if (*dp == '=')
885 				*dp++ = '\0';
886 			*dp++ = '\0';	/* terminate name */
887 
888 			debug("DELETE CANDIDATE: \"%s\"\n", name);
889 			if (!drop_var_from_set(name, nvars, localvars))
890 				continue;
891 
892 			if (hdelete_r(name, htab, flag) == 0)
893 				debug("DELETE ERROR ##############################\n");
894 
895 			continue;
896 		}
897 		*dp++ = '\0';	/* terminate name */
898 
899 		/* parse value; deal with escapes */
900 		for (value = sp = dp; *dp && (*dp != sep); ++dp) {
901 			if ((*dp == '\\') && *(dp + 1))
902 				++dp;
903 			*sp++ = *dp;
904 		}
905 		*sp++ = '\0';	/* terminate value */
906 		++dp;
907 
908 		if (*name == 0) {
909 			debug("INSERT: unable to use an empty key\n");
910 			__set_errno(EINVAL);
911 			free(data);
912 			return 0;
913 		}
914 
915 		/* Skip variables which are not supposed to be processed */
916 		if (!drop_var_from_set(name, nvars, localvars))
917 			continue;
918 
919 		/* enter into hash table */
920 		e.key = name;
921 		e.data = value;
922 
923 		hsearch_r(e, ENTER, &rv, htab, flag);
924 		if (rv == NULL)
925 			printf("himport_r: can't insert \"%s=%s\" into hash table\n",
926 				name, value);
927 
928 		debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n",
929 			htab, htab->filled, htab->size,
930 			rv, name, value);
931 	} while ((dp < data + size) && *dp);	/* size check needed for text */
932 						/* without '\0' termination */
933 	debug("INSERT: free(data = %p)\n", data);
934 	free(data);
935 
936 	/* process variables which were not considered */
937 	for (i = 0; i < nvars; i++) {
938 		if (localvars[i] == NULL)
939 			continue;
940 		/*
941 		 * All variables which were not deleted from the variable list
942 		 * were not present in the imported env
943 		 * This could mean two things:
944 		 * a) if the variable was present in current env, we delete it
945 		 * b) if the variable was not present in current env, we notify
946 		 *    it might be a typo
947 		 */
948 		if (hdelete_r(localvars[i], htab, flag) == 0)
949 			printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]);
950 		else
951 			printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]);
952 	}
953 
954 	debug("INSERT: done\n");
955 	return 1;		/* everything OK */
956 }
957 
958 /*
959  * hwalk_r()
960  */
961 
962 /*
963  * Walk all of the entries in the hash, calling the callback for each one.
964  * this allows some generic operation to be performed on each element.
965  */
966 int hwalk_r(struct hsearch_data *htab, int (*callback)(ENTRY *))
967 {
968 	int i;
969 	int retval;
970 
971 	for (i = 1; i <= htab->size; ++i) {
972 		if (htab->table[i].used > 0) {
973 			retval = callback(&htab->table[i].entry);
974 			if (retval)
975 				return retval;
976 		}
977 	}
978 
979 	return 0;
980 }
981