xref: /rk3399_rockchip-uboot/tools/env/fw_env_main.c (revision 9884f44cab5d1ce944b1dc087c9bb8db0efb5160)
16aff3115Swdenk /*
2bc11756dSGrant Erickson  * (C) Copyright 2000-2008
36aff3115Swdenk  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
46aff3115Swdenk  *
51a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
66aff3115Swdenk  */
76aff3115Swdenk 
86aff3115Swdenk /*
93bac3513Swdenk  * Command line user interface to firmware (=U-Boot) environment.
106aff3115Swdenk  *
116aff3115Swdenk  * Implements:
12a8a752c0SMarek Vasut  *	fw_printenv [ -a key ] [[ -n name ] | [ name ... ]]
13bc11756dSGrant Erickson  *              - prints the value of a single environment variable
14bc11756dSGrant Erickson  *                "name", the ``name=value'' pairs of one or more
15bc11756dSGrant Erickson  *                environment variables "name", or the whole
16bc11756dSGrant Erickson  *                environment if no names are specified.
17a8a752c0SMarek Vasut  *	fw_setenv [ -a key ] name [ value ... ]
186aff3115Swdenk  *		- If a name without any values is given, the variable
196aff3115Swdenk  *		  with this name is deleted from the environment;
206aff3115Swdenk  *		  otherwise, all "value" arguments are concatenated,
21bc11756dSGrant Erickson  *		  separated by single blank characters, and the
226aff3115Swdenk  *		  resulting string is assigned to the environment
236aff3115Swdenk  *		  variable "name"
24a8a752c0SMarek Vasut  *
25a8a752c0SMarek Vasut  * If '-a key' is specified, the env block is encrypted with AES 128 CBC.
26a8a752c0SMarek Vasut  * The 'key' argument is in the format of 32 hexadecimal numbers (16 bytes
27a8a752c0SMarek Vasut  * of AES key), eg. '-a aabbccddeeff00112233445566778899'.
286aff3115Swdenk  */
296aff3115Swdenk 
30e4a223f0SJoe Hershberger #include <fcntl.h>
31e4a223f0SJoe Hershberger #include <getopt.h>
326aff3115Swdenk #include <stdio.h>
336aff3115Swdenk #include <string.h>
346aff3115Swdenk #include <stdlib.h>
35e4a223f0SJoe Hershberger #include <sys/file.h>
36e4a223f0SJoe Hershberger #include <unistd.h>
376aff3115Swdenk #include "fw_env.h"
386aff3115Swdenk 
396aff3115Swdenk #define	CMD_PRINTENV	"fw_printenv"
406aff3115Swdenk #define CMD_SETENV	"fw_setenv"
416aff3115Swdenk 
42bd7b26f8SStefano Babic static struct option long_options[] = {
43bd7b26f8SStefano Babic 	{"script", required_argument, NULL, 's'},
44bd7b26f8SStefano Babic 	{"help", no_argument, NULL, 'h'},
45bd7b26f8SStefano Babic 	{NULL, 0, NULL, 0}
46bd7b26f8SStefano Babic };
47bd7b26f8SStefano Babic 
48bd7b26f8SStefano Babic void usage(void)
49bd7b26f8SStefano Babic {
50bd7b26f8SStefano Babic 
51bd7b26f8SStefano Babic 	fprintf(stderr, "fw_printenv/fw_setenv, "
52bd7b26f8SStefano Babic 		"a command line interface to U-Boot environment\n\n"
53*9884f44cSMichael Heimpold #ifndef CONFIG_FILE
54a8a752c0SMarek Vasut 		"usage:\tfw_printenv [-a key] [-n] [variable name]\n"
55a8a752c0SMarek Vasut 		"\tfw_setenv [-a key] [variable name] [variable value]\n"
56*9884f44cSMichael Heimpold #else
57*9884f44cSMichael Heimpold 		"usage:\tfw_printenv [-c /my/fw_env.config] [-a key] [-n] [variable name]\n"
58*9884f44cSMichael Heimpold 		"\tfw_setenv [-c /my/fw_env.config] [-a key] [variable name] [variable value]\n"
59*9884f44cSMichael Heimpold #endif
60bd7b26f8SStefano Babic 		"\tfw_setenv -s [ file ]\n"
61bd7b26f8SStefano Babic 		"\tfw_setenv -s - < [ file ]\n\n"
62bd7b26f8SStefano Babic 		"The file passed as argument contains only pairs "
63bd7b26f8SStefano Babic 		"name / value\n"
64bd7b26f8SStefano Babic 		"Example:\n"
65bd7b26f8SStefano Babic 		"# Any line starting with # is treated as comment\n"
66bd7b26f8SStefano Babic 		"\n"
67bd7b26f8SStefano Babic 		"\t      netdev         eth0\n"
68bd7b26f8SStefano Babic 		"\t      kernel_addr    400000\n"
69bd7b26f8SStefano Babic 		"\t      var1\n"
70bd7b26f8SStefano Babic 		"\t      var2          The quick brown fox jumps over the "
71bd7b26f8SStefano Babic 		"lazy dog\n"
72bd7b26f8SStefano Babic 		"\n"
73bd7b26f8SStefano Babic 		"A variable without value will be dropped. It is possible\n"
74bd7b26f8SStefano Babic 		"to put any number of spaces between the fields, but any\n"
75bd7b26f8SStefano Babic 		"space inside the value is treated as part of the value "
76bd7b26f8SStefano Babic 		"itself.\n\n"
77bd7b26f8SStefano Babic 	);
78bd7b26f8SStefano Babic }
79bd7b26f8SStefano Babic 
80e4a223f0SJoe Hershberger int main(int argc, char *argv[])
816aff3115Swdenk {
826aff3115Swdenk 	char *p;
836aff3115Swdenk 	char *cmdname = *argv;
84bd7b26f8SStefano Babic 	char *script_file = NULL;
85bd7b26f8SStefano Babic 	int c;
86e4a223f0SJoe Hershberger 	const char *lockname = "/var/lock/" CMD_PRINTENV ".lock";
87e4a223f0SJoe Hershberger 	int lockfd = -1;
88e4a223f0SJoe Hershberger 	int retval = EXIT_SUCCESS;
89e4a223f0SJoe Hershberger 
907a546db2SMike Frysinger 	lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
91e4a223f0SJoe Hershberger 	if (-1 == lockfd) {
92e4a223f0SJoe Hershberger 		fprintf(stderr, "Error opening lock file %s\n", lockname);
93e4a223f0SJoe Hershberger 		return EXIT_FAILURE;
94e4a223f0SJoe Hershberger 	}
95e4a223f0SJoe Hershberger 
96e4a223f0SJoe Hershberger 	if (-1 == flock(lockfd, LOCK_EX)) {
97e4a223f0SJoe Hershberger 		fprintf(stderr, "Error locking file %s\n", lockname);
98e4a223f0SJoe Hershberger 		close(lockfd);
99e4a223f0SJoe Hershberger 		return EXIT_FAILURE;
100e4a223f0SJoe Hershberger 	}
1016aff3115Swdenk 
1026aff3115Swdenk 	if ((p = strrchr (cmdname, '/')) != NULL) {
1036aff3115Swdenk 		cmdname = p + 1;
1046aff3115Swdenk 	}
1056aff3115Swdenk 
106*9884f44cSMichael Heimpold 	while ((c = getopt_long (argc, argv, "a:c:ns:h",
107bd7b26f8SStefano Babic 		long_options, NULL)) != EOF) {
108bd7b26f8SStefano Babic 		switch (c) {
109a8a752c0SMarek Vasut 		case 'a':
110a8a752c0SMarek Vasut 			/* AES key, handled later */
111a8a752c0SMarek Vasut 			break;
112*9884f44cSMichael Heimpold 		case 'c':
113*9884f44cSMichael Heimpold 			/* handled later */
114*9884f44cSMichael Heimpold 			break;
115122bc088SDaniel Hobi 		case 'n':
116122bc088SDaniel Hobi 			/* handled in fw_printenv */
117122bc088SDaniel Hobi 			break;
118bd7b26f8SStefano Babic 		case 's':
119bd7b26f8SStefano Babic 			script_file = optarg;
120bd7b26f8SStefano Babic 			break;
121bd7b26f8SStefano Babic 		case 'h':
122bd7b26f8SStefano Babic 			usage();
123e4a223f0SJoe Hershberger 			goto exit;
12429ccd7c3SDaniel Hobi 		default: /* '?' */
12529ccd7c3SDaniel Hobi 			fprintf(stderr, "Try `%s --help' for more information."
12629ccd7c3SDaniel Hobi 				"\n", cmdname);
127e4a223f0SJoe Hershberger 			retval = EXIT_FAILURE;
128e4a223f0SJoe Hershberger 			goto exit;
129bd7b26f8SStefano Babic 		}
130bd7b26f8SStefano Babic 	}
131bd7b26f8SStefano Babic 
1326aff3115Swdenk 	if (strcmp(cmdname, CMD_PRINTENV) == 0) {
133bc11756dSGrant Erickson 		if (fw_printenv(argc, argv) != 0)
134e4a223f0SJoe Hershberger 			retval = EXIT_FAILURE;
1356aff3115Swdenk 	} else if (strcmp(cmdname, CMD_SETENV) == 0) {
136bd7b26f8SStefano Babic 		if (!script_file) {
1376aff3115Swdenk 			if (fw_setenv(argc, argv) != 0)
138e4a223f0SJoe Hershberger 				retval = EXIT_FAILURE;
139bd7b26f8SStefano Babic 		} else {
140bd7b26f8SStefano Babic 			if (fw_parse_script(script_file) != 0)
141e4a223f0SJoe Hershberger 				retval = EXIT_FAILURE;
142bd7b26f8SStefano Babic 		}
143e4a223f0SJoe Hershberger 	} else {
1446aff3115Swdenk 		fprintf(stderr,
1456aff3115Swdenk 			"Identity crisis - may be called as `" CMD_PRINTENV
1466aff3115Swdenk 			"' or as `" CMD_SETENV "' but not as `%s'\n",
1476aff3115Swdenk 			cmdname);
148e4a223f0SJoe Hershberger 		retval = EXIT_FAILURE;
149e4a223f0SJoe Hershberger 	}
150e4a223f0SJoe Hershberger 
151e4a223f0SJoe Hershberger exit:
152e4a223f0SJoe Hershberger 	flock(lockfd, LOCK_UN);
153e4a223f0SJoe Hershberger 	close(lockfd);
154e4a223f0SJoe Hershberger 	return retval;
1556aff3115Swdenk }
156