| /* |
| * (C) Copyright 2000-2008 |
| * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
| * |
| * SPDX-License-Identifier: GPL-2.0+ |
| */ |
| |
| /* |
| * Command line user interface to firmware (=U-Boot) environment. |
| * |
| * Implements: |
| * fw_printenv [[ -n name ] | [ name ... ]] |
| * - prints the value of a single environment variable |
| * "name", the ``name=value'' pairs of one or more |
| * environment variables "name", or the whole |
| * environment if no names are specified. |
| * fw_setenv name [ value ... ] |
| * - If a name without any values is given, the variable |
| * with this name is deleted from the environment; |
| * otherwise, all "value" arguments are concatenated, |
| * separated by single blank characters, and the |
| * resulting string is assigned to the environment |
| * variable "name" |
| */ |
| |
| #include <fcntl.h> |
| #include <getopt.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <sys/file.h> |
| #include <unistd.h> |
| #include "fw_env.h" |
| |
| #define CMD_PRINTENV "fw_printenv" |
| #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] [variable name]\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 main(int argc, char *argv[]) |
| { |
| char *p; |
| char *cmdname = *argv; |
| char *script_file = NULL; |
| int c; |
| const char *lockname = "/var/lock/" CMD_PRINTENV ".lock"; |
| int lockfd = -1; |
| int retval = EXIT_SUCCESS; |
| |
| lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| if (-1 == lockfd) { |
| fprintf(stderr, "Error opening lock file %s\n", lockname); |
| return EXIT_FAILURE; |
| } |
| |
| if (-1 == flock(lockfd, LOCK_EX)) { |
| fprintf(stderr, "Error locking file %s\n", lockname); |
| close(lockfd); |
| return EXIT_FAILURE; |
| } |
| |
| if ((p = strrchr (cmdname, '/')) != NULL) { |
| cmdname = p + 1; |
| } |
| |
| while ((c = getopt_long (argc, argv, "ns:h", |
| long_options, NULL)) != EOF) { |
| switch (c) { |
| case 'n': |
| /* handled in fw_printenv */ |
| break; |
| case 's': |
| script_file = optarg; |
| break; |
| case 'h': |
| usage(); |
| goto exit; |
| default: /* '?' */ |
| fprintf(stderr, "Try `%s --help' for more information." |
| "\n", cmdname); |
| retval = EXIT_FAILURE; |
| goto exit; |
| } |
| } |
| |
| if (strcmp(cmdname, CMD_PRINTENV) == 0) { |
| if (fw_printenv(argc, argv) != 0) |
| retval = EXIT_FAILURE; |
| } else if (strcmp(cmdname, CMD_SETENV) == 0) { |
| if (!script_file) { |
| if (fw_setenv(argc, argv) != 0) |
| retval = EXIT_FAILURE; |
| } else { |
| if (fw_parse_script(script_file) != 0) |
| retval = EXIT_FAILURE; |
| } |
| } else { |
| fprintf(stderr, |
| "Identity crisis - may be called as `" CMD_PRINTENV |
| "' or as `" CMD_SETENV "' but not as `%s'\n", |
| cmdname); |
| retval = EXIT_FAILURE; |
| } |
| |
| exit: |
| flock(lockfd, LOCK_UN); |
| close(lockfd); |
| return retval; |
| } |