]> git.sur5r.net Git - u-boot/blob - tools/env/fw_env_main.c
tools: env: parse aes key / suppress flag into argument struct
[u-boot] / tools / env / fw_env_main.c
1 /*
2  * (C) Copyright 2000-2008
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * Command line user interface to firmware (=U-Boot) environment.
10  *
11  * Implements:
12  *      fw_printenv [ -a key ] [[ -n name ] | [ name ... ]]
13  *              - prints the value of a single environment variable
14  *                "name", the ``name=value'' pairs of one or more
15  *                environment variables "name", or the whole
16  *                environment if no names are specified.
17  *      fw_setenv [ -a key ] name [ value ... ]
18  *              - If a name without any values is given, the variable
19  *                with this name is deleted from the environment;
20  *                otherwise, all "value" arguments are concatenated,
21  *                separated by single blank characters, and the
22  *                resulting string is assigned to the environment
23  *                variable "name"
24  *
25  * If '-a key' is specified, the env block is encrypted with AES 128 CBC.
26  * The 'key' argument is in the format of 32 hexadecimal numbers (16 bytes
27  * of AES key), eg. '-a aabbccddeeff00112233445566778899'.
28  */
29
30 #include <fcntl.h>
31 #include <getopt.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <sys/file.h>
36 #include <unistd.h>
37 #include "fw_env.h"
38
39 #define CMD_PRINTENV    "fw_printenv"
40 #define CMD_SETENV      "fw_setenv"
41
42 static struct option long_options[] = {
43         {"script", required_argument, NULL, 's'},
44         {"help", no_argument, NULL, 'h'},
45         {NULL, 0, NULL, 0}
46 };
47
48 struct common_args common_args;
49 struct printenv_args printenv_args;
50 struct setenv_args setenv_args;
51
52 void usage(void)
53 {
54
55         fprintf(stderr, "fw_printenv/fw_setenv, "
56                 "a command line interface to U-Boot environment\n\n"
57 #ifndef CONFIG_FILE
58                 "usage:\tfw_printenv [-a key] [-n] [variable name]\n"
59                 "\tfw_setenv [-a key] [variable name] [variable value]\n"
60 #else
61                 "usage:\tfw_printenv [-c /my/fw_env.config] [-a key] [-n] [variable name]\n"
62                 "\tfw_setenv [-c /my/fw_env.config] [-a key] [variable name] [variable value]\n"
63 #endif
64                 "\tfw_setenv -s [ file ]\n"
65                 "\tfw_setenv -s - < [ file ]\n\n"
66                 "The file passed as argument contains only pairs "
67                 "name / value\n"
68                 "Example:\n"
69                 "# Any line starting with # is treated as comment\n"
70                 "\n"
71                 "\t      netdev         eth0\n"
72                 "\t      kernel_addr    400000\n"
73                 "\t      var1\n"
74                 "\t      var2          The quick brown fox jumps over the "
75                 "lazy dog\n"
76                 "\n"
77                 "A variable without value will be dropped. It is possible\n"
78                 "to put any number of spaces between the fields, but any\n"
79                 "space inside the value is treated as part of the value "
80                 "itself.\n\n"
81         );
82 }
83
84 int parse_printenv_args(int argc, char *argv[])
85 {
86         int c;
87
88 #ifdef CONFIG_FILE
89         common_args.config_file = CONFIG_FILE;
90 #endif
91
92         while ((c = getopt_long (argc, argv, "a:c:ns:h",
93                 long_options, NULL)) != EOF) {
94                 switch (c) {
95                 case 'a':
96                         if (parse_aes_key(optarg, common_args.aes_key)) {
97                                 fprintf(stderr, "AES key parse error\n");
98                                 return EXIT_FAILURE;
99                         }
100                         common_args.aes_flag = 1;
101                         break;
102 #ifdef CONFIG_FILE
103                 case 'c':
104                         common_args.config_file = optarg;
105                         break;
106 #endif
107                 case 'n':
108                         printenv_args.name_suppress = 1;
109                         break;
110                 case 'h':
111                         usage();
112                         exit(EXIT_SUCCESS);
113                         break;
114                 default: /* '?' */
115                         usage();
116                         exit(EXIT_FAILURE);
117                         break;
118                 }
119         }
120         return 0;
121 }
122
123 int parse_setenv_args(int argc, char *argv[])
124 {
125         int c;
126
127 #ifdef CONFIG_FILE
128         common_args.config_file = CONFIG_FILE;
129 #endif
130
131         while ((c = getopt_long (argc, argv, "a:c:ns:h",
132                 long_options, NULL)) != EOF) {
133                 switch (c) {
134                 case 'a':
135                         if (parse_aes_key(optarg, common_args.aes_key)) {
136                                 fprintf(stderr, "AES key parse error\n");
137                                 return EXIT_FAILURE;
138                         }
139                         common_args.aes_flag = 1;
140                         break;
141 #ifdef CONFIG_FILE
142                 case 'c':
143                         common_args.config_file = optarg;
144                         break;
145 #endif
146                 case 's':
147                         setenv_args.script_file = optarg;
148                         break;
149                 case 'h':
150                         usage();
151                         exit(EXIT_SUCCESS);
152                         break;
153                 default: /* '?' */
154                         usage();
155                         exit(EXIT_FAILURE);
156                         break;
157                 }
158         }
159         return 0;
160 }
161
162 int main(int argc, char *argv[])
163 {
164         char *cmdname = *argv;
165         const char *lockname = "/var/lock/" CMD_PRINTENV ".lock";
166         int lockfd = -1;
167         int retval = EXIT_SUCCESS;
168
169         if (strrchr(cmdname, '/') != NULL)
170                 cmdname = strrchr(cmdname, '/') + 1;
171
172         if (strcmp(cmdname, CMD_PRINTENV) == 0) {
173                 if (parse_printenv_args(argc, argv))
174                         exit(EXIT_FAILURE);
175         } else if (strcmp(cmdname, CMD_SETENV) == 0) {
176                 if (parse_setenv_args(argc, argv))
177                         exit(EXIT_FAILURE);
178         } else {
179                 fprintf(stderr,
180                         "Identity crisis - may be called as `%s' or as `%s' but not as `%s'\n",
181                         CMD_PRINTENV, CMD_SETENV, cmdname);
182                 exit(EXIT_FAILURE);
183         }
184
185         lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
186         if (-1 == lockfd) {
187                 fprintf(stderr, "Error opening lock file %s\n", lockname);
188                 return EXIT_FAILURE;
189         }
190
191         if (-1 == flock(lockfd, LOCK_EX)) {
192                 fprintf(stderr, "Error locking file %s\n", lockname);
193                 close(lockfd);
194                 return EXIT_FAILURE;
195         }
196
197         if (strcmp(cmdname, CMD_PRINTENV) == 0) {
198                 if (fw_printenv(argc, argv) != 0)
199                         retval = EXIT_FAILURE;
200         } else if (strcmp(cmdname, CMD_SETENV) == 0) {
201                 if (!setenv_args.script_file) {
202                         if (fw_setenv(argc, argv) != 0)
203                                 retval = EXIT_FAILURE;
204                 } else {
205                         if (fw_parse_script(setenv_args.script_file) != 0)
206                                 retval = EXIT_FAILURE;
207                 }
208         }
209
210         flock(lockfd, LOCK_UN);
211         close(lockfd);
212         return retval;
213 }