/*
 * (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 [ -a key ] [[ -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 [ -a key ] 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"
 *
 * If '-a key' is specified, the env block is encrypted with AES 128 CBC.
 * The 'key' argument is in the format of 32 hexadecimal numbers (16 bytes
 * of AES key), eg. '-a aabbccddeeff00112233445566778899'.
 */

#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 int do_printenv;

static struct option long_options[] = {
	{"aes", required_argument, NULL, 'a'},
	{"config", required_argument, NULL, 'c'},
	{"help", no_argument, NULL, 'h'},
	{"script", required_argument, NULL, 's'},
	{"noheader", required_argument, NULL, 'n'},
	{"lock", required_argument, NULL, 'l'},
	{NULL, 0, NULL, 0}
};

static struct env_opts env_opts;

/* setenv options */
static int noheader;

/* getenv options */
static char *script_file;

void usage_printenv(void)
{

	fprintf(stderr,
		"Usage: fw_printenv [OPTIONS]... [VARIABLE]...\n"
		"Print variables from U-Boot environment\n"
		"\n"
		" -h, --help           print this help.\n"
#ifdef CONFIG_ENV_AES
		" -a, --aes            aes key to access environment\n"
#endif
#ifdef CONFIG_FILE
		" -c, --config         configuration file, default:" CONFIG_FILE "\n"
#endif
		" -n, --noheader       do not repeat variable name in output\n"
		" -l, --lock           lock node, default:/var/lock\n"
		"\n");
}

void usage_setenv(void)
{
	fprintf(stderr,
		"Usage: fw_setenv [OPTIONS]... [VARIABLE]...\n"
		"Modify variables in U-Boot environment\n"
		"\n"
		" -h, --help           print this help.\n"
#ifdef CONFIG_ENV_AES
		" -a, --aes            aes key to access environment\n"
#endif
#ifdef CONFIG_FILE
		" -c, --config         configuration file, default:" CONFIG_FILE "\n"
#endif
		" -l, --lock           lock node, default:/var/lock\n"
		" -s, --script         batch mode to minimize writes\n"
		"\n"
		"Examples:\n"
		"  fw_setenv foo bar   set variable foo equal bar\n"
		"  fw_setenv foo       clear variable foo\n"
		"  fw_setenv --script file run batch script\n"
		"\n"
		"Script Syntax:\n"
		"  key [space] value\n"
		"  lines starting with '#' are treated as comment\n"
		"\n"
		"  A variable without value will be deleted. Any number of spaces are\n"
		"  allowed between key and value. Space inside of the value is treated\n"
		"  as part of the value itself.\n"
		"\n"
		"Script Example:\n"
		"  netdev         eth0\n"
		"  kernel_addr    400000\n"
		"  foo            empty empty empty    empty empty empty\n"
		"  bar\n"
		"\n");
}

static void parse_common_args(int argc, char *argv[])
{
	int c;

#ifdef CONFIG_FILE
	env_opts.config_file = CONFIG_FILE;
#endif

	while ((c = getopt_long(argc, argv, ":a:c:l:h", long_options, NULL)) !=
	       EOF) {
		switch (c) {
		case 'a':
			if (parse_aes_key(optarg, env_opts.aes_key)) {
				fprintf(stderr, "AES key parse error\n");
				exit(EXIT_FAILURE);
			}
			env_opts.aes_flag = 1;
			break;
#ifdef CONFIG_FILE
		case 'c':
			env_opts.config_file = optarg;
			break;
#endif
		case 'l':
			env_opts.lockname = optarg;
			break;
		case 'h':
			do_printenv ? usage_printenv() : usage_setenv();
			exit(EXIT_SUCCESS);
			break;
		default:
			/* ignore unknown options */
			break;
		}
	}

	/* Reset getopt for the next pass. */
	opterr = 1;
	optind = 1;
}

int parse_printenv_args(int argc, char *argv[])
{
	int c;

	parse_common_args(argc, argv);

	while ((c = getopt_long(argc, argv, "a:c:ns:l:h", long_options, NULL))
		!= EOF) {
		switch (c) {
		case 'n':
			noheader = 1;
			break;
		case 'a':
		case 'c':
		case 'h':
		case 'l':
			/* ignore common options */
			break;
		default: /* '?' */
			usage_printenv();
			exit(EXIT_FAILURE);
			break;
		}
	}
	return 0;
}

int parse_setenv_args(int argc, char *argv[])
{
	int c;

	parse_common_args(argc, argv);

	while ((c = getopt_long(argc, argv, "a:c:ns:l:h", long_options, NULL))
		!= EOF) {
		switch (c) {
		case 's':
			script_file = optarg;
			break;
		case 'a':
		case 'c':
		case 'h':
		case 'l':
			/* ignore common options */
			break;
		default: /* '?' */
			usage_setenv();
			exit(EXIT_FAILURE);
			break;
		}
	}
	return 0;
}

int main(int argc, char *argv[])
{
	char *lockname = "/var/lock/" CMD_PRINTENV ".lock";
	int lockfd = -1;
	int retval = EXIT_SUCCESS;
	char *_cmdname;

	_cmdname = *argv;
	if (strrchr(_cmdname, '/') != NULL)
		_cmdname = strrchr(_cmdname, '/') + 1;

	if (strcmp(_cmdname, CMD_PRINTENV) == 0) {
		do_printenv = 1;
	} else if (strcmp(_cmdname, CMD_SETENV) == 0) {
		do_printenv = 0;
	} else {
		fprintf(stderr,
			"Identity crisis - may be called as `%s' or as `%s' but not as `%s'\n",
			CMD_PRINTENV, CMD_SETENV, _cmdname);
		exit(EXIT_FAILURE);
	}

	if (do_printenv) {
		if (parse_printenv_args(argc, argv))
			exit(EXIT_FAILURE);
	} else {
		if (parse_setenv_args(argc, argv))
			exit(EXIT_FAILURE);
	}

	/* shift parsed flags, jump to non-option arguments */
	argc -= optind;
	argv += optind;

	if (env_opts.lockname) {
		lockname = malloc(sizeof(env_opts.lockname) +
				sizeof(CMD_PRINTENV) + 10);
		if (!lockname) {
			fprintf(stderr, "Unable allocate memory");
			exit(EXIT_FAILURE);
		}

		sprintf(lockname, "%s/%s.lock",
			env_opts.lockname, CMD_PRINTENV);
	}

	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 (do_printenv) {
		if (fw_printenv(argc, argv, noheader, &env_opts) != 0)
			retval = EXIT_FAILURE;
	} else {
		if (!script_file) {
			if (fw_setenv(argc, argv, &env_opts) != 0)
				retval = EXIT_FAILURE;
		} else {
			if (fw_parse_script(script_file, &env_opts) != 0)
				retval = EXIT_FAILURE;
		}
	}

	if (env_opts.lockname)
		free(lockname);

	flock(lockfd, LOCK_UN);
	close(lockfd);
	return retval;
}
