16aff3115Swdenk /* 2bc11756dSGrant Erickson * (C) Copyright 2000-2008 36aff3115Swdenk * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 46aff3115Swdenk * 5*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 66aff3115Swdenk */ 76aff3115Swdenk 86aff3115Swdenk /* 93bac3513Swdenk * Command line user interface to firmware (=U-Boot) environment. 106aff3115Swdenk * 116aff3115Swdenk * Implements: 12bc11756dSGrant Erickson * fw_printenv [[ -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. 176aff3115Swdenk * fw_setenv 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" 246aff3115Swdenk */ 256aff3115Swdenk 26e4a223f0SJoe Hershberger #include <fcntl.h> 27e4a223f0SJoe Hershberger #include <getopt.h> 286aff3115Swdenk #include <stdio.h> 296aff3115Swdenk #include <string.h> 306aff3115Swdenk #include <stdlib.h> 31e4a223f0SJoe Hershberger #include <sys/file.h> 32e4a223f0SJoe Hershberger #include <unistd.h> 336aff3115Swdenk #include "fw_env.h" 346aff3115Swdenk 356aff3115Swdenk #define CMD_PRINTENV "fw_printenv" 366aff3115Swdenk #define CMD_SETENV "fw_setenv" 376aff3115Swdenk 38bd7b26f8SStefano Babic static struct option long_options[] = { 39bd7b26f8SStefano Babic {"script", required_argument, NULL, 's'}, 40bd7b26f8SStefano Babic {"help", no_argument, NULL, 'h'}, 41bd7b26f8SStefano Babic {NULL, 0, NULL, 0} 42bd7b26f8SStefano Babic }; 43bd7b26f8SStefano Babic 44bd7b26f8SStefano Babic void usage(void) 45bd7b26f8SStefano Babic { 46bd7b26f8SStefano Babic 47bd7b26f8SStefano Babic fprintf(stderr, "fw_printenv/fw_setenv, " 48bd7b26f8SStefano Babic "a command line interface to U-Boot environment\n\n" 49122bc088SDaniel Hobi "usage:\tfw_printenv [-n] [variable name]\n" 50bd7b26f8SStefano Babic "\tfw_setenv [variable name] [variable value]\n" 51bd7b26f8SStefano Babic "\tfw_setenv -s [ file ]\n" 52bd7b26f8SStefano Babic "\tfw_setenv -s - < [ file ]\n\n" 53bd7b26f8SStefano Babic "The file passed as argument contains only pairs " 54bd7b26f8SStefano Babic "name / value\n" 55bd7b26f8SStefano Babic "Example:\n" 56bd7b26f8SStefano Babic "# Any line starting with # is treated as comment\n" 57bd7b26f8SStefano Babic "\n" 58bd7b26f8SStefano Babic "\t netdev eth0\n" 59bd7b26f8SStefano Babic "\t kernel_addr 400000\n" 60bd7b26f8SStefano Babic "\t var1\n" 61bd7b26f8SStefano Babic "\t var2 The quick brown fox jumps over the " 62bd7b26f8SStefano Babic "lazy dog\n" 63bd7b26f8SStefano Babic "\n" 64bd7b26f8SStefano Babic "A variable without value will be dropped. It is possible\n" 65bd7b26f8SStefano Babic "to put any number of spaces between the fields, but any\n" 66bd7b26f8SStefano Babic "space inside the value is treated as part of the value " 67bd7b26f8SStefano Babic "itself.\n\n" 68bd7b26f8SStefano Babic ); 69bd7b26f8SStefano Babic } 70bd7b26f8SStefano Babic 71e4a223f0SJoe Hershberger int main(int argc, char *argv[]) 726aff3115Swdenk { 736aff3115Swdenk char *p; 746aff3115Swdenk char *cmdname = *argv; 75bd7b26f8SStefano Babic char *script_file = NULL; 76bd7b26f8SStefano Babic int c; 77e4a223f0SJoe Hershberger const char *lockname = "/var/lock/" CMD_PRINTENV ".lock"; 78e4a223f0SJoe Hershberger int lockfd = -1; 79e4a223f0SJoe Hershberger int retval = EXIT_SUCCESS; 80e4a223f0SJoe Hershberger 817a546db2SMike Frysinger lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666); 82e4a223f0SJoe Hershberger if (-1 == lockfd) { 83e4a223f0SJoe Hershberger fprintf(stderr, "Error opening lock file %s\n", lockname); 84e4a223f0SJoe Hershberger return EXIT_FAILURE; 85e4a223f0SJoe Hershberger } 86e4a223f0SJoe Hershberger 87e4a223f0SJoe Hershberger if (-1 == flock(lockfd, LOCK_EX)) { 88e4a223f0SJoe Hershberger fprintf(stderr, "Error locking file %s\n", lockname); 89e4a223f0SJoe Hershberger close(lockfd); 90e4a223f0SJoe Hershberger return EXIT_FAILURE; 91e4a223f0SJoe Hershberger } 926aff3115Swdenk 936aff3115Swdenk if ((p = strrchr (cmdname, '/')) != NULL) { 946aff3115Swdenk cmdname = p + 1; 956aff3115Swdenk } 966aff3115Swdenk 97122bc088SDaniel Hobi while ((c = getopt_long (argc, argv, "ns:h", 98bd7b26f8SStefano Babic long_options, NULL)) != EOF) { 99bd7b26f8SStefano Babic switch (c) { 100122bc088SDaniel Hobi case 'n': 101122bc088SDaniel Hobi /* handled in fw_printenv */ 102122bc088SDaniel Hobi break; 103bd7b26f8SStefano Babic case 's': 104bd7b26f8SStefano Babic script_file = optarg; 105bd7b26f8SStefano Babic break; 106bd7b26f8SStefano Babic case 'h': 107bd7b26f8SStefano Babic usage(); 108e4a223f0SJoe Hershberger goto exit; 10929ccd7c3SDaniel Hobi default: /* '?' */ 11029ccd7c3SDaniel Hobi fprintf(stderr, "Try `%s --help' for more information." 11129ccd7c3SDaniel Hobi "\n", cmdname); 112e4a223f0SJoe Hershberger retval = EXIT_FAILURE; 113e4a223f0SJoe Hershberger goto exit; 114bd7b26f8SStefano Babic } 115bd7b26f8SStefano Babic } 116bd7b26f8SStefano Babic 1176aff3115Swdenk if (strcmp(cmdname, CMD_PRINTENV) == 0) { 118bc11756dSGrant Erickson if (fw_printenv(argc, argv) != 0) 119e4a223f0SJoe Hershberger retval = EXIT_FAILURE; 1206aff3115Swdenk } else if (strcmp(cmdname, CMD_SETENV) == 0) { 121bd7b26f8SStefano Babic if (!script_file) { 1226aff3115Swdenk if (fw_setenv(argc, argv) != 0) 123e4a223f0SJoe Hershberger retval = EXIT_FAILURE; 124bd7b26f8SStefano Babic } else { 125bd7b26f8SStefano Babic if (fw_parse_script(script_file) != 0) 126e4a223f0SJoe Hershberger retval = EXIT_FAILURE; 127bd7b26f8SStefano Babic } 128e4a223f0SJoe Hershberger } else { 1296aff3115Swdenk fprintf(stderr, 1306aff3115Swdenk "Identity crisis - may be called as `" CMD_PRINTENV 1316aff3115Swdenk "' or as `" CMD_SETENV "' but not as `%s'\n", 1326aff3115Swdenk cmdname); 133e4a223f0SJoe Hershberger retval = EXIT_FAILURE; 134e4a223f0SJoe Hershberger } 135e4a223f0SJoe Hershberger 136e4a223f0SJoe Hershberger exit: 137e4a223f0SJoe Hershberger flock(lockfd, LOCK_UN); 138e4a223f0SJoe Hershberger close(lockfd); 139e4a223f0SJoe Hershberger return retval; 1406aff3115Swdenk } 141