Tools: set multiple variable with fw_setenv utility
Add a sort of batch mode to fw_setenv, allowing to set multiple variables in one shot, without updating the flash after each set as now. It is added the possibility to pass a config file with a list of pairs <variable, value> to be set, separated by a TAB character. Signed-off-by: Stefano Babic <sbabic@denx.de>
This commit is contained in:
		
							parent
							
								
									3746a5e65c
								
							
						
					
					
						commit
						bd7b26f879
					
				|  | @ -45,8 +45,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "fw_env.h" | #include "fw_env.h" | ||||||
| 
 | 
 | ||||||
| #define	CMD_GETENV	"fw_printenv" | #define WHITESPACE(c) ((c == '\t') || (c == ' ')) | ||||||
| #define	CMD_SETENV	"fw_setenv" |  | ||||||
| 
 | 
 | ||||||
| #define min(x, y) ({				\ | #define min(x, y) ({				\ | ||||||
| 	typeof(x) _min1 = (x);			\ | 	typeof(x) _min1 = (x);			\ | ||||||
|  | @ -210,7 +209,6 @@ static char default_environment[] = { | ||||||
| 
 | 
 | ||||||
| static int flash_io (int mode); | static int flash_io (int mode); | ||||||
| static char *envmatch (char * s1, char * s2); | static char *envmatch (char * s1, char * s2); | ||||||
| static int env_init (void); |  | ||||||
| static int parse_config (void); | static int parse_config (void); | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_FILE) | #if defined(CONFIG_FILE) | ||||||
|  | @ -225,6 +223,22 @@ static inline ulong getenvsize (void) | ||||||
| 	return rc; | 	return rc; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static char *fw_string_blank(char *s, int noblank) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	int len = strlen(s); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < len; i++, s++) { | ||||||
|  | 		if ((noblank && !WHITESPACE(*s)) || | ||||||
|  | 			(!noblank && WHITESPACE(*s))) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	if (i == len) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Search the environment for a variable. |  * Search the environment for a variable. | ||||||
|  * Return the value, if found, or NULL, if not found. |  * Return the value, if found, or NULL, if not found. | ||||||
|  | @ -233,7 +247,7 @@ char *fw_getenv (char *name) | ||||||
| { | { | ||||||
| 	char *env, *nxt; | 	char *env, *nxt; | ||||||
| 
 | 
 | ||||||
| 	if (env_init ()) | 	if (fw_env_open()) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
| 	for (env = environment.data; *env; env = nxt + 1) { | 	for (env = environment.data; *env; env = nxt + 1) { | ||||||
|  | @ -264,7 +278,7 @@ int fw_printenv (int argc, char *argv[]) | ||||||
| 	int i, n_flag; | 	int i, n_flag; | ||||||
| 	int rc = 0; | 	int rc = 0; | ||||||
| 
 | 
 | ||||||
| 	if (env_init ()) | 	if (fw_env_open()) | ||||||
| 		return -1; | 		return -1; | ||||||
| 
 | 
 | ||||||
| 	if (argc == 1) {		/* Print all env variables  */ | 	if (argc == 1) {		/* Print all env variables  */ | ||||||
|  | @ -327,30 +341,34 @@ int fw_printenv (int argc, char *argv[]) | ||||||
| 	return rc; | 	return rc; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | int fw_env_close(void) | ||||||
|  * Deletes or sets environment variables. Returns -1 and sets errno error codes: |  | ||||||
|  * 0	  - OK |  | ||||||
|  * EINVAL - need at least 1 argument |  | ||||||
|  * EROFS  - certain variables ("ethaddr", "serial#") cannot be |  | ||||||
|  *	    modified or deleted |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| int fw_setenv (int argc, char *argv[]) |  | ||||||
| { | { | ||||||
| 	int i, len; | 	/*
 | ||||||
| 	char *env, *nxt; | 	 * Update CRC | ||||||
| 	char *oldval = NULL; | 	 */ | ||||||
| 	char *name; | 	*environment.crc = crc32(0, (uint8_t *) environment.data, ENV_SIZE); | ||||||
| 
 | 
 | ||||||
| 	if (argc < 2) { | 	/* write environment back to flash */ | ||||||
| 		errno = EINVAL; | 	if (flash_io(O_RDWR)) { | ||||||
|  | 		fprintf(stderr, | ||||||
|  | 			"Error: can't write fw_env to flash\n"); | ||||||
| 			return -1; | 			return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (env_init ()) | 	return 0; | ||||||
| 		return -1; | } | ||||||
| 
 | 
 | ||||||
| 	name = argv[1]; | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set/Clear a single variable in the environment. | ||||||
|  |  * This is called in sequence to update the environment | ||||||
|  |  * in RAM without updating the copy in flash after each set | ||||||
|  |  */ | ||||||
|  | int fw_env_write(char *name, char *value) | ||||||
|  | { | ||||||
|  | 	int len; | ||||||
|  | 	char *env, *nxt; | ||||||
|  | 	char *oldval = NULL; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * search if variable with this name already exists | 	 * search if variable with this name already exists | ||||||
|  | @ -358,7 +376,7 @@ int fw_setenv (int argc, char *argv[]) | ||||||
| 	for (nxt = env = environment.data; *env; env = nxt + 1) { | 	for (nxt = env = environment.data; *env; env = nxt + 1) { | ||||||
| 		for (nxt = env; *nxt; ++nxt) { | 		for (nxt = env; *nxt; ++nxt) { | ||||||
| 			if (nxt >= &environment.data[ENV_SIZE]) { | 			if (nxt >= &environment.data[ENV_SIZE]) { | ||||||
| 				fprintf (stderr, "## Error: " | 				fprintf(stderr, "## Error: " | ||||||
| 					"environment not terminated\n"); | 					"environment not terminated\n"); | ||||||
| 				errno = EINVAL; | 				errno = EINVAL; | ||||||
| 				return -1; | 				return -1; | ||||||
|  | @ -396,8 +414,8 @@ int fw_setenv (int argc, char *argv[]) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Delete only ? */ | 	/* Delete only ? */ | ||||||
| 	if (argc < 3) | 	if (!value || !strlen(value)) | ||||||
| 		goto WRITE_FLASH; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Append new definition at the end | 	 * Append new definition at the end | ||||||
|  | @ -411,41 +429,202 @@ int fw_setenv (int argc, char *argv[]) | ||||||
| 	 */ | 	 */ | ||||||
| 	len = strlen (name) + 2; | 	len = strlen (name) + 2; | ||||||
| 	/* add '=' for first arg, ' ' for all others */ | 	/* add '=' for first arg, ' ' for all others */ | ||||||
| 	for (i = 2; i < argc; ++i) { | 	len += strlen(value) + 1; | ||||||
| 		len += strlen (argv[i]) + 1; | 
 | ||||||
| 	} |  | ||||||
| 	if (len > (&environment.data[ENV_SIZE] - env)) { | 	if (len > (&environment.data[ENV_SIZE] - env)) { | ||||||
| 		fprintf (stderr, | 		fprintf (stderr, | ||||||
| 			"Error: environment overflow, \"%s\" deleted\n", | 			"Error: environment overflow, \"%s\" deleted\n", | ||||||
| 			name); | 			name); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	while ((*env = *name++) != '\0') | 	while ((*env = *name++) != '\0') | ||||||
| 		env++; | 		env++; | ||||||
| 	for (i = 2; i < argc; ++i) { | 	*env = '='; | ||||||
| 		char *val = argv[i]; | 	while ((*++env = *value++) != '\0') | ||||||
| 
 | 		; | ||||||
| 		*env = (i == 2) ? '=' : ' '; |  | ||||||
| 		while ((*++env = *val++) != '\0'); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/* end is marked with double '\0' */ | 	/* end is marked with double '\0' */ | ||||||
| 	*++env = '\0'; | 	*++env = '\0'; | ||||||
| 
 | 
 | ||||||
|   WRITE_FLASH: | 	return 0; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	/*
 | /*
 | ||||||
| 	 * Update CRC |  * Deletes or sets environment variables. Returns -1 and sets errno error codes: | ||||||
|  |  * 0	  - OK | ||||||
|  |  * EINVAL - need at least 1 argument | ||||||
|  |  * EROFS  - certain variables ("ethaddr", "serial#") cannot be | ||||||
|  |  *	    modified or deleted | ||||||
|  |  * | ||||||
|  */ |  */ | ||||||
| 	*environment.crc = crc32 (0, (uint8_t *) environment.data, ENV_SIZE); | int fw_setenv(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	int i, len; | ||||||
|  | 	char *name; | ||||||
|  | 	char *value = NULL; | ||||||
|  | 	char *tmpval = NULL; | ||||||
| 
 | 
 | ||||||
| 	/* write environment back to flash */ | 	if (argc < 2) { | ||||||
| 	if (flash_io (O_RDWR)) { | 		errno = EINVAL; | ||||||
| 		fprintf (stderr, "Error: can't write fw_env to flash\n"); |  | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	if (fw_env_open()) { | ||||||
|  | 		fprintf(stderr, "Error: environment not initialized\n"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	name = argv[1]; | ||||||
|  | 
 | ||||||
|  | 	len = strlen(name) + 2; | ||||||
|  | 	for (i = 2; i < argc; ++i) | ||||||
|  | 		len += strlen(argv[i]) + 1; | ||||||
|  | 
 | ||||||
|  | 	/* Allocate enough place to the data string */ | ||||||
|  | 	for (i = 2; i < argc; ++i) { | ||||||
|  | 		char *val = argv[i]; | ||||||
|  | 		if (!value) { | ||||||
|  | 			value = (char *)malloc(len - strlen(name)); | ||||||
|  | 			if (!value) { | ||||||
|  | 				fprintf(stderr, | ||||||
|  | 				"Cannot malloc %u bytes: %s\n", | ||||||
|  | 				len - strlen(name), strerror(errno)); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 			memset(value, 0, len - strlen(name)); | ||||||
|  | 			tmpval = value; | ||||||
|  | 		} | ||||||
|  | 		if (i != 2) | ||||||
|  | 			*tmpval++ = ' '; | ||||||
|  | 		while (*val != '\0') | ||||||
|  | 			*tmpval++ = *val++; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fw_env_write(name, value); | ||||||
|  | 
 | ||||||
|  | 	if (value) | ||||||
|  | 		free(value); | ||||||
|  | 
 | ||||||
|  | 	return fw_env_close(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Parse  a file  and configure the u-boot variables. | ||||||
|  |  * The script file has a very simple format, as follows: | ||||||
|  |  * | ||||||
|  |  * Each line has a couple with name, value: | ||||||
|  |  * <white spaces>variable_name<white spaces>variable_value | ||||||
|  |  * | ||||||
|  |  * Both variable_name and variable_value are interpreted as strings. | ||||||
|  |  * Any character after <white spaces> and before ending \r\n is interpreted | ||||||
|  |  * as variable's value (no comment allowed on these lines !) | ||||||
|  |  * | ||||||
|  |  * Comments are allowed if the first character in the line is # | ||||||
|  |  * | ||||||
|  |  * Returns -1 and sets errno error codes: | ||||||
|  |  * 0	  - OK | ||||||
|  |  * -1     - Error | ||||||
|  |  */ | ||||||
|  | int fw_parse_script(char *fname) | ||||||
|  | { | ||||||
|  | 	FILE *fp; | ||||||
|  | 	char dump[1024];	/* Maximum line length in the file */ | ||||||
|  | 	char *name; | ||||||
|  | 	char *val; | ||||||
|  | 	int lineno = 0; | ||||||
|  | 	int len; | ||||||
|  | 	int ret = 0; | ||||||
|  | 
 | ||||||
|  | 	if (fw_env_open()) { | ||||||
|  | 		fprintf(stderr, "Error: environment not initialized\n"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (strcmp(fname, "-") == 0) | ||||||
|  | 		fp = stdin; | ||||||
|  | 	else { | ||||||
|  | 		fp = fopen(fname, "r"); | ||||||
|  | 		if (fp == NULL) { | ||||||
|  | 			fprintf(stderr, "I cannot open %s for reading\n", | ||||||
|  | 				 fname); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	while (fgets(dump, sizeof(dump), fp)) { | ||||||
|  | 		lineno++; | ||||||
|  | 		len = strlen(dump); | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * Read a whole line from the file. If the line is too long | ||||||
|  | 		 * or is not terminated, reports an error and exit. | ||||||
|  | 		 */ | ||||||
|  | 		if (dump[len - 1] != '\n') { | ||||||
|  | 			fprintf(stderr, | ||||||
|  | 			"Line %d not corrected terminated or too long\n", | ||||||
|  | 				lineno); | ||||||
|  | 			ret = -1; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Drop ending line feed / carriage return */ | ||||||
|  | 		while (len > 0 && (dump[len - 1] == '\n' || | ||||||
|  | 				dump[len - 1] == '\r')) { | ||||||
|  | 			dump[len - 1] = '\0'; | ||||||
|  | 			len--; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Skip comment or empty lines */ | ||||||
|  | 		if ((len == 0) || dump[0] == '#') | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * Search for variable's name, | ||||||
|  | 		 * remove leading whitespaces | ||||||
|  | 		 */ | ||||||
|  | 		name = fw_string_blank(dump, 1); | ||||||
|  | 		if (!name) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		/* The first white space is the end of variable name */ | ||||||
|  | 		val = fw_string_blank(name, 0); | ||||||
|  | 		len = strlen(name); | ||||||
|  | 		if (val) { | ||||||
|  | 			*val++ = '\0'; | ||||||
|  | 			if ((val - name) < len) | ||||||
|  | 				val = fw_string_blank(val, 1); | ||||||
|  | 			else | ||||||
|  | 				val = NULL; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | #ifdef DEBUG | ||||||
|  | 		fprintf(stderr, "Setting %s : %s\n", | ||||||
|  | 			name, val ? val : " removed"); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * If there is an error setting a variable, | ||||||
|  | 		 * try to save the environment and returns an error | ||||||
|  | 		 */ | ||||||
|  | 		if (fw_env_write(name, val)) { | ||||||
|  | 			fprintf(stderr, | ||||||
|  | 			"fw_env_write returns with error : %s\n", | ||||||
|  | 				strerror(errno)); | ||||||
|  | 			ret = -1; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Close file if not stdin */ | ||||||
|  | 	if (strcmp(fname, "-") != 0) | ||||||
|  | 		fclose(fp); | ||||||
|  | 
 | ||||||
|  | 	ret |= fw_env_close(); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -880,7 +1059,7 @@ static char *envmatch (char * s1, char * s2) | ||||||
| /*
 | /*
 | ||||||
|  * Prevent confusion if running from erased flash memory |  * Prevent confusion if running from erased flash memory | ||||||
|  */ |  */ | ||||||
| static int env_init (void) | int fw_env_open(void) | ||||||
| { | { | ||||||
| 	int crc0, crc0_ok; | 	int crc0, crc0_ok; | ||||||
| 	char flag0; | 	char flag0; | ||||||
|  |  | ||||||
|  | @ -50,5 +50,9 @@ | ||||||
| extern int   fw_printenv(int argc, char *argv[]); | extern int   fw_printenv(int argc, char *argv[]); | ||||||
| extern char *fw_getenv  (char *name); | extern char *fw_getenv  (char *name); | ||||||
| extern int fw_setenv  (int argc, char *argv[]); | extern int fw_setenv  (int argc, char *argv[]); | ||||||
|  | extern int fw_parse_script(char *fname); | ||||||
|  | extern int fw_env_open(void); | ||||||
|  | extern int fw_env_write(char *name, char *value); | ||||||
|  | extern int fw_env_close(void); | ||||||
| 
 | 
 | ||||||
| extern unsigned	long  crc32	 (unsigned long, const unsigned char *, unsigned); | extern unsigned	long  crc32	 (unsigned long, const unsigned char *, unsigned); | ||||||
|  |  | ||||||
|  | @ -42,34 +42,87 @@ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <getopt.h> | ||||||
| #include "fw_env.h" | #include "fw_env.h" | ||||||
| 
 | 
 | ||||||
| #define	CMD_PRINTENV	"fw_printenv" | #define	CMD_PRINTENV	"fw_printenv" | ||||||
| #define CMD_SETENV	"fw_setenv" | #define CMD_SETENV	"fw_setenv" | ||||||
| 
 | 
 | ||||||
|  | static struct option long_options[] = { | ||||||
|  | 	{"script", required_argument, NULL, 's'}, | ||||||
|  | 	{"help", no_argument, NULL, 'h'}, | ||||||
|  | 	{NULL, 0, NULL, 0} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void usage(void) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	fprintf(stderr, "fw_printenv/fw_setenv, " | ||||||
|  | 		"a command line interface to U-Boot environment\n\n" | ||||||
|  | 		"usage:\tfw_printenv\n" | ||||||
|  | 		"\tfw_setenv [variable name] [variable value]\n" | ||||||
|  | 		"\tfw_setenv -s [ file ]\n" | ||||||
|  | 		"\tfw_setenv -s - < [ file ]\n\n" | ||||||
|  | 		"The file passed as argument contains only pairs " | ||||||
|  | 		"name / value\n" | ||||||
|  | 		"Example:\n" | ||||||
|  | 		"# Any line starting with # is treated as comment\n" | ||||||
|  | 		"\n" | ||||||
|  | 		"\t      netdev         eth0\n" | ||||||
|  | 		"\t      kernel_addr    400000\n" | ||||||
|  | 		"\t      var1\n" | ||||||
|  | 		"\t      var2          The quick brown fox jumps over the " | ||||||
|  | 		"lazy dog\n" | ||||||
|  | 		"\n" | ||||||
|  | 		"A variable without value will be dropped. It is possible\n" | ||||||
|  | 		"to put any number of spaces between the fields, but any\n" | ||||||
|  | 		"space inside the value is treated as part of the value " | ||||||
|  | 		"itself.\n\n" | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int | int | ||||||
| main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||||
| { | { | ||||||
| 	char *p; | 	char *p; | ||||||
| 	char *cmdname = *argv; | 	char *cmdname = *argv; | ||||||
|  | 	char *script_file = NULL; | ||||||
|  | 	int c; | ||||||
| 
 | 
 | ||||||
| 	if ((p = strrchr (cmdname, '/')) != NULL) { | 	if ((p = strrchr (cmdname, '/')) != NULL) { | ||||||
| 		cmdname = p + 1; | 		cmdname = p + 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	while ((c = getopt_long (argc, argv, "s:h", | ||||||
|  | 		long_options, NULL)) != EOF) { | ||||||
|  | 		switch (c) { | ||||||
|  | 		case 's': | ||||||
|  | 			script_file = optarg; | ||||||
|  | 			break; | ||||||
|  | 		case 'h': | ||||||
|  | 			usage(); | ||||||
|  | 			return EXIT_SUCCESS; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	if (strcmp(cmdname, CMD_PRINTENV) == 0) { | 	if (strcmp(cmdname, CMD_PRINTENV) == 0) { | ||||||
| 
 | 
 | ||||||
| 		if (fw_printenv (argc, argv) != 0) | 		if (fw_printenv (argc, argv) != 0) | ||||||
| 			return (EXIT_FAILURE); | 			return EXIT_FAILURE; | ||||||
| 
 | 
 | ||||||
| 		return (EXIT_SUCCESS); | 		return EXIT_SUCCESS; | ||||||
| 
 | 
 | ||||||
| 	} else if (strcmp(cmdname, CMD_SETENV) == 0) { | 	} else if (strcmp(cmdname, CMD_SETENV) == 0) { | ||||||
|  | 		if (!script_file) { | ||||||
|  | 			if (fw_setenv(argc, argv) != 0) | ||||||
|  | 				return EXIT_FAILURE; | ||||||
|  | 		} else { | ||||||
|  | 			if (fw_parse_script(script_file) != 0) | ||||||
|  | 				return EXIT_FAILURE; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		if (fw_setenv (argc, argv) != 0) | 		return EXIT_SUCCESS; | ||||||
| 			return (EXIT_FAILURE); |  | ||||||
| 
 |  | ||||||
| 		return (EXIT_SUCCESS); |  | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -77,5 +130,5 @@ main(int argc, char *argv[]) | ||||||
| 		"Identity crisis - may be called as `" CMD_PRINTENV | 		"Identity crisis - may be called as `" CMD_PRINTENV | ||||||
| 		"' or as `" CMD_SETENV "' but not as `%s'\n", | 		"' or as `" CMD_SETENV "' but not as `%s'\n", | ||||||
| 		cmdname); | 		cmdname); | ||||||
| 	return (EXIT_FAILURE); | 	return EXIT_FAILURE; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue