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