diff options
| -rw-r--r-- | lib/hashtable.c | 50 | 
1 files changed, 42 insertions, 8 deletions
| diff --git a/lib/hashtable.c b/lib/hashtable.c index f3f47de88..670a704a4 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -607,22 +607,32 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep,   * himport()   */ -/* Check whether variable name is amongst vars[] */ -static int is_var_in_set(const char *name, int nvars, char * const vars[]) +/* + * Check whether variable 'name' is amongst vars[], + * and remove all instances by setting the pointer to NULL + */ +static int drop_var_from_set(const char *name, int nvars, char * vars[])  {  	int i = 0; +	int res = 0;  	/* No variables specified means process all of them */  	if (nvars == 0)  		return 1;  	for (i = 0; i < nvars; i++) { -		if (!strcmp(name, vars[i])) -			return 1; +		if (vars[i] == NULL) +			continue; +		/* If we found it, delete all of them */ +		if (!strcmp(name, vars[i])) { +			vars[i] = NULL; +			res = 1; +		}  	} -	debug("Skipping non-listed variable %s\n", name); +	if (!res) +		debug("Skipping non-listed variable %s\n", name); -	return 0; +	return res;  }  /* @@ -665,6 +675,8 @@ int himport_r(struct hsearch_data *htab,  		int nvars, char * const vars[], int do_apply)  {  	char *data, *sp, *dp, *name, *value; +	char *localvars[nvars]; +	int i;  	/* Test for correct arguments.  */  	if (htab == NULL) { @@ -681,6 +693,10 @@ int himport_r(struct hsearch_data *htab,  	memcpy(data, env, size);  	dp = data; +	/* make a local copy of the list of variables */ +	if (nvars) +		memcpy(localvars, vars, sizeof(vars[0]) * nvars); +  	if ((flag & H_NOCLEAR) == 0) {  		/* Destroy old hash table if one exists */  		debug("Destroy Hash Table: %p table = %p\n", htab, @@ -749,7 +765,7 @@ int himport_r(struct hsearch_data *htab,  			*dp++ = '\0';	/* terminate name */  			debug("DELETE CANDIDATE: \"%s\"\n", name); -			if (!is_var_in_set(name, nvars, vars)) +			if (!drop_var_from_set(name, nvars, localvars))  				continue;  			if (hdelete_r(name, htab, do_apply) == 0) @@ -769,7 +785,7 @@ int himport_r(struct hsearch_data *htab,  		++dp;  		/* Skip variables which are not supposed to be processed */ -		if (!is_var_in_set(name, nvars, vars)) +		if (!drop_var_from_set(name, nvars, localvars))  			continue;  		/* enter into hash table */ @@ -809,6 +825,24 @@ int himport_r(struct hsearch_data *htab,  	debug("INSERT: free(data = %p)\n", data);  	free(data); +	/* process variables which were not considered */ +	for (i = 0; i < nvars; i++) { +		if (localvars[i] == NULL) +			continue; +		/* +		 * All variables which were not deleted from the variable list +		 * were not present in the imported env +		 * This could mean two things: +		 * a) if the variable was present in current env, we delete it +		 * b) if the variable was not present in current env, we notify +		 *    it might be a typo +		 */ +		if (hdelete_r(localvars[i], htab, do_apply) == 0) +			printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]); +		else +			printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]); +	} +  	debug("INSERT: done\n");  	return 1;		/* everything OK */  } |