blob: 0c9f918fc674a72236ac4e04469b208e07855a1c [file] [log] [blame]
wdenk34b613e2002-12-17 01:51:00 +00001/*
Grant Erickson73a4e5e2008-05-06 20:16:15 -07002 * (C) Copyright 2000-2008
wdenk34b613e2002-12-17 01:51:00 +00003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
Wolfgang Denkbd8ec7e2013-10-07 13:07:26 +02005 * SPDX-License-Identifier: GPL-2.0+
wdenk34b613e2002-12-17 01:51:00 +00006 */
7
8/*
wdenkef5fe752003-03-12 10:41:04 +00009 * Command line user interface to firmware (=U-Boot) environment.
wdenk34b613e2002-12-17 01:51:00 +000010 *
11 * Implements:
Marek Vasut05ed2a52014-03-05 19:59:52 +010012 * fw_printenv [ -a key ] [[ -n name ] | [ name ... ]]
Grant Erickson73a4e5e2008-05-06 20:16:15 -070013 * - 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.
Marek Vasut05ed2a52014-03-05 19:59:52 +010017 * fw_setenv [ -a key ] name [ value ... ]
wdenk34b613e2002-12-17 01:51:00 +000018 * - 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,
Grant Erickson73a4e5e2008-05-06 20:16:15 -070021 * separated by single blank characters, and the
wdenk34b613e2002-12-17 01:51:00 +000022 * resulting string is assigned to the environment
23 * variable "name"
Marek Vasut05ed2a52014-03-05 19:59:52 +010024 *
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'.
wdenk34b613e2002-12-17 01:51:00 +000028 */
29
Joe Hershberger3f1f1752012-10-03 09:38:49 +000030#include <fcntl.h>
31#include <getopt.h>
wdenk34b613e2002-12-17 01:51:00 +000032#include <stdio.h>
33#include <string.h>
34#include <stdlib.h>
Joe Hershberger3f1f1752012-10-03 09:38:49 +000035#include <sys/file.h>
36#include <unistd.h>
wdenk34b613e2002-12-17 01:51:00 +000037#include "fw_env.h"
38
39#define CMD_PRINTENV "fw_printenv"
40#define CMD_SETENV "fw_setenv"
41
Stefano Babicada628b2010-05-24 12:08:16 +020042static struct option long_options[] = {
43 {"script", required_argument, NULL, 's'},
44 {"help", no_argument, NULL, 'h'},
45 {NULL, 0, NULL, 0}
46};
47
Andreas Fenkart33e91772015-12-09 13:13:23 +010048struct printenv_args printenv_args;
49struct setenv_args setenv_args;
50
Stefano Babicada628b2010-05-24 12:08:16 +020051void usage(void)
52{
53
54 fprintf(stderr, "fw_printenv/fw_setenv, "
55 "a command line interface to U-Boot environment\n\n"
Michael Heimpold211e17b2015-10-27 22:34:49 +010056#ifndef CONFIG_FILE
Marek Vasut05ed2a52014-03-05 19:59:52 +010057 "usage:\tfw_printenv [-a key] [-n] [variable name]\n"
58 "\tfw_setenv [-a key] [variable name] [variable value]\n"
Michael Heimpold211e17b2015-10-27 22:34:49 +010059#else
60 "usage:\tfw_printenv [-c /my/fw_env.config] [-a key] [-n] [variable name]\n"
61 "\tfw_setenv [-c /my/fw_env.config] [-a key] [variable name] [variable value]\n"
62#endif
Stefano Babicada628b2010-05-24 12:08:16 +020063 "\tfw_setenv -s [ file ]\n"
64 "\tfw_setenv -s - < [ file ]\n\n"
65 "The file passed as argument contains only pairs "
66 "name / value\n"
67 "Example:\n"
68 "# Any line starting with # is treated as comment\n"
69 "\n"
70 "\t netdev eth0\n"
71 "\t kernel_addr 400000\n"
72 "\t var1\n"
73 "\t var2 The quick brown fox jumps over the "
74 "lazy dog\n"
75 "\n"
76 "A variable without value will be dropped. It is possible\n"
77 "to put any number of spaces between the fields, but any\n"
78 "space inside the value is treated as part of the value "
79 "itself.\n\n"
80 );
81}
82
Andreas Fenkart33e91772015-12-09 13:13:23 +010083int parse_printenv_args(int argc, char *argv[])
wdenk34b613e2002-12-17 01:51:00 +000084{
Stefano Babicada628b2010-05-24 12:08:16 +020085 int c;
wdenk34b613e2002-12-17 01:51:00 +000086
Michael Heimpold211e17b2015-10-27 22:34:49 +010087 while ((c = getopt_long (argc, argv, "a:c:ns:h",
Stefano Babicada628b2010-05-24 12:08:16 +020088 long_options, NULL)) != EOF) {
89 switch (c) {
Marek Vasut05ed2a52014-03-05 19:59:52 +010090 case 'a':
91 /* AES key, handled later */
92 break;
Michael Heimpold211e17b2015-10-27 22:34:49 +010093 case 'c':
94 /* handled later */
95 break;
Daniel Hobi6c554262010-09-15 19:46:26 +020096 case 'n':
97 /* handled in fw_printenv */
98 break;
Andreas Fenkart33e91772015-12-09 13:13:23 +010099 case 'h':
100 usage();
101 exit(EXIT_SUCCESS);
102 break;
103 default: /* '?' */
104 usage();
105 exit(EXIT_FAILURE);
106 break;
107 }
108 }
109 return 0;
110}
111
112int parse_setenv_args(int argc, char *argv[])
113{
114 int c;
115
116 while ((c = getopt_long (argc, argv, "a:c:ns:h",
117 long_options, NULL)) != EOF) {
118 switch (c) {
119 case 'a':
120 /* AES key, handled later */
121 break;
122 case 'c':
123 /* handled later */
124 break;
Stefano Babicada628b2010-05-24 12:08:16 +0200125 case 's':
Andreas Fenkart33e91772015-12-09 13:13:23 +0100126 setenv_args.script_file = optarg;
Stefano Babicada628b2010-05-24 12:08:16 +0200127 break;
128 case 'h':
129 usage();
Andreas Fenkart33e91772015-12-09 13:13:23 +0100130 exit(EXIT_SUCCESS);
131 break;
Daniel Hobi6a20a322010-09-16 14:36:09 +0200132 default: /* '?' */
Andreas Fenkart33e91772015-12-09 13:13:23 +0100133 usage();
134 exit(EXIT_FAILURE);
135 break;
Stefano Babicada628b2010-05-24 12:08:16 +0200136 }
137 }
Andreas Fenkart33e91772015-12-09 13:13:23 +0100138 return 0;
139}
140
141int main(int argc, char *argv[])
142{
143 char *cmdname = *argv;
144 const char *lockname = "/var/lock/" CMD_PRINTENV ".lock";
145 int lockfd = -1;
146 int retval = EXIT_SUCCESS;
147
148 if (strrchr(cmdname, '/') != NULL)
149 cmdname = strrchr(cmdname, '/') + 1;
Stefano Babicada628b2010-05-24 12:08:16 +0200150
wdenk34b613e2002-12-17 01:51:00 +0000151 if (strcmp(cmdname, CMD_PRINTENV) == 0) {
Andreas Fenkart33e91772015-12-09 13:13:23 +0100152 if (parse_printenv_args(argc, argv))
153 exit(EXIT_FAILURE);
154 } else if (strcmp(cmdname, CMD_SETENV) == 0) {
155 if (parse_setenv_args(argc, argv))
156 exit(EXIT_FAILURE);
157 } else {
158 fprintf(stderr,
159 "Identity crisis - may be called as `%s' or as `%s' but not as `%s'\n",
160 CMD_PRINTENV, CMD_SETENV, cmdname);
161 exit(EXIT_FAILURE);
162 }
163
164 lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
165 if (-1 == lockfd) {
166 fprintf(stderr, "Error opening lock file %s\n", lockname);
167 return EXIT_FAILURE;
168 }
169
170 if (-1 == flock(lockfd, LOCK_EX)) {
171 fprintf(stderr, "Error locking file %s\n", lockname);
172 close(lockfd);
173 return EXIT_FAILURE;
174 }
175
176 if (strcmp(cmdname, CMD_PRINTENV) == 0) {
Joe Hershberger3f1f1752012-10-03 09:38:49 +0000177 if (fw_printenv(argc, argv) != 0)
178 retval = EXIT_FAILURE;
wdenk34b613e2002-12-17 01:51:00 +0000179 } else if (strcmp(cmdname, CMD_SETENV) == 0) {
Andreas Fenkart33e91772015-12-09 13:13:23 +0100180 if (!setenv_args.script_file) {
Stefano Babicada628b2010-05-24 12:08:16 +0200181 if (fw_setenv(argc, argv) != 0)
Joe Hershberger3f1f1752012-10-03 09:38:49 +0000182 retval = EXIT_FAILURE;
Stefano Babicada628b2010-05-24 12:08:16 +0200183 } else {
Andreas Fenkart33e91772015-12-09 13:13:23 +0100184 if (fw_parse_script(setenv_args.script_file) != 0)
Joe Hershberger3f1f1752012-10-03 09:38:49 +0000185 retval = EXIT_FAILURE;
Stefano Babicada628b2010-05-24 12:08:16 +0200186 }
wdenk34b613e2002-12-17 01:51:00 +0000187 }
188
Joe Hershberger3f1f1752012-10-03 09:38:49 +0000189 flock(lockfd, LOCK_UN);
190 close(lockfd);
191 return retval;
wdenk34b613e2002-12-17 01:51:00 +0000192}