/*
 * (C) Copyright 2011 Free Electrons
 * David Wagner <david.wagner@free-electrons.com>
 *
 * Inspired from envcrc.c:
 * (C) Copyright 2001
 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/* We want the GNU version of basename() */
#define _GNU_SOURCE

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include "compiler.h"
#include <u-boot/crc.h>
#include <version.h>

#define CRC_SIZE sizeof(uint32_t)

static void usage(const char *exec_name)
{
	fprintf(stderr, "%s [-h] [-r] [-b] [-p <byte>] -s <environment partition size> -o <output> <input file>\n"
	       "\n"
	       "This tool takes a key=value input file (same as would a `printenv' show) and generates the corresponding environment image, ready to be flashed.\n"
	       "\n"
	       "\tThe input file is in format:\n"
	       "\t\tkey1=value1\n"
	       "\t\tkey2=value2\n"
	       "\t\t...\n"
	       "\t-r : the environment has multiple copies in flash\n"
	       "\t-b : the target is big endian (default is little endian)\n"
	       "\t-p <byte> : fill the image with <byte> bytes instead of 0xff bytes\n"
	       "\t-V : print version information and exit\n"
	       "\n"
	       "If the input file is \"-\", data is read from standard input\n",
	       exec_name);
}

long int xstrtol(const char *s)
{
	long int tmp;

	errno = 0;
	tmp = strtol(s, NULL, 0);
	if (!errno)
		return tmp;

	if (errno == ERANGE)
		fprintf(stderr, "Bad integer format: %s\n",  s);
	else
		fprintf(stderr, "Error while parsing %s: %s\n", s,
				strerror(errno));

	exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
	uint32_t crc, targetendian_crc;
	const char *txt_filename = NULL, *bin_filename = NULL;
	int txt_fd, bin_fd;
	unsigned char *dataptr, *envptr;
	unsigned char *filebuf = NULL;
	unsigned int filesize = 0, envsize = 0, datasize = 0;
	int bigendian = 0;
	int redundant = 0;
	unsigned char padbyte = 0xff;

	int option;
	int ret = EXIT_SUCCESS;

	struct stat txt_file_stat;

	int fp, ep;
	const char *prg;

	prg = basename(argv[0]);

	/* Turn off getopt()'s internal error message */
	opterr = 0;

	/* Parse the cmdline */
	while ((option = getopt(argc, argv, ":s:o:rbp:hV")) != -1) {
		switch (option) {
		case 's':
			datasize = xstrtol(optarg);
			break;
		case 'o':
			bin_filename = strdup(optarg);
			if (!bin_filename) {
				fprintf(stderr, "Can't strdup() the output filename\n");
				return EXIT_FAILURE;
			}
			break;
		case 'r':
			redundant = 1;
			break;
		case 'b':
			bigendian = 1;
			break;
		case 'p':
			padbyte = xstrtol(optarg);
			break;
		case 'h':
			usage(prg);
			return EXIT_SUCCESS;
		case 'V':
			printf("%s version %s\n", prg, PLAIN_VERSION);
			return EXIT_SUCCESS;
		case ':':
			fprintf(stderr, "Missing argument for option -%c\n",
				optopt);
			usage(prg);
			return EXIT_FAILURE;
		default:
			fprintf(stderr, "Wrong option -%c\n", optopt);
			usage(prg);
			return EXIT_FAILURE;
		}
	}

	/* Check datasize and allocate the data */
	if (datasize == 0) {
		fprintf(stderr, "Please specify the size of the environment partition.\n");
		usage(prg);
		return EXIT_FAILURE;
	}

	dataptr = malloc(datasize * sizeof(*dataptr));
	if (!dataptr) {
		fprintf(stderr, "Can't alloc %d bytes for dataptr.\n",
				datasize);
		return EXIT_FAILURE;
	}

	/*
	 * envptr points to the beginning of the actual environment (after the
	 * crc and possible `redundant' byte
	 */
	envsize = datasize - (CRC_SIZE + redundant);
	envptr = dataptr + CRC_SIZE + redundant;

	/* Pad the environment with the padding byte */
	memset(envptr, padbyte, envsize);

	/* Open the input file ... */
	if (optind >= argc || strcmp(argv[optind], "-") == 0) {
		int readbytes = 0;
		int readlen = sizeof(*envptr) * 4096;
		txt_fd = STDIN_FILENO;

		do {
			filebuf = realloc(filebuf, readlen);
			if (!filebuf) {
				fprintf(stderr, "Can't realloc memory for the input file buffer\n");
				return EXIT_FAILURE;
			}
			readbytes = read(txt_fd, filebuf + filesize, readlen);
			if (errno) {
				fprintf(stderr, "Error while reading stdin: %s\n",
						strerror(errno));
				return EXIT_FAILURE;
			}
			filesize += readbytes;
		} while (readbytes == readlen);

	} else {
		txt_filename = argv[optind];
		txt_fd = open(txt_filename, O_RDONLY);
		if (txt_fd == -1) {
			fprintf(stderr, "Can't open \"%s\": %s\n",
					txt_filename, strerror(errno));
			return EXIT_FAILURE;
		}
		/* ... and check it */
		ret = fstat(txt_fd, &txt_file_stat);
		if (ret == -1) {
			fprintf(stderr, "Can't stat() on \"%s\": %s\n",
					txt_filename, strerror(errno));
			return EXIT_FAILURE;
		}

		filesize = txt_file_stat.st_size;

		filebuf = mmap(NULL, sizeof(*envptr) * filesize, PROT_READ,
			       MAP_PRIVATE, txt_fd, 0);
		if (filebuf == MAP_FAILED) {
			fprintf(stderr, "mmap (%zu bytes) failed: %s\n",
					sizeof(*envptr) * filesize,
					strerror(errno));
			fprintf(stderr, "Falling back to read()\n");

			filebuf = malloc(sizeof(*envptr) * filesize);
			ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
			if (ret != sizeof(*envptr) * filesize) {
				fprintf(stderr, "Can't read the whole input file (%zu bytes): %s\n",
					sizeof(*envptr) * filesize,
					strerror(errno));

				return EXIT_FAILURE;
			}
		}
		ret = close(txt_fd);
	}
	/* The +1 is for the additionnal ending \0. See below. */
	if (filesize + 1 > envsize) {
		fprintf(stderr, "The input file is larger than the environment partition size\n");
		return EXIT_FAILURE;
	}

	/* Replace newlines separating variables with \0 */
	for (fp = 0, ep = 0 ; fp < filesize ; fp++) {
		if (filebuf[fp] == '\n') {
			if (ep == 0) {
				/*
				 * Newlines at the beginning of the file ?
				 * Ignore them.
				 */
				continue;
			} else if (filebuf[fp-1] == '\\') {
				/*
				 * Embedded newline in a variable.
				 *
				 * The backslash was added to the envptr; rewind
				 * and replace it with a newline
				 */
				ep--;
				envptr[ep++] = '\n';
			} else {
				/* End of a variable */
				envptr[ep++] = '\0';
			}
		} else {
			envptr[ep++] = filebuf[fp];
		}
	}
	/*
	 * Make sure there is a final '\0'
	 * And do it again on the next byte to mark the end of the environment.
	 */
	if (envptr[ep-1] != '\0') {
		envptr[ep++] = '\0';
		/*
		 * The text file doesn't have an ending newline.  We need to
		 * check the env size again to make sure we have room for two \0
		 */
		if (ep >= envsize) {
			fprintf(stderr, "The environment file is too large for the target environment storage\n");
			return EXIT_FAILURE;
		}
		envptr[ep] = '\0';
	} else {
		envptr[ep] = '\0';
	}

	/* Computes the CRC and put it at the beginning of the data */
	crc = crc32(0, envptr, envsize);
	targetendian_crc = bigendian ? cpu_to_be32(crc) : cpu_to_le32(crc);

	memcpy(dataptr, &targetendian_crc, sizeof(targetendian_crc));
	if (redundant)
		dataptr[sizeof(targetendian_crc)] = 1;

	if (!bin_filename || strcmp(bin_filename, "-") == 0) {
		bin_fd = STDOUT_FILENO;
	} else {
		bin_fd = creat(bin_filename, S_IRUSR | S_IWUSR | S_IRGRP |
					     S_IWGRP);
		if (bin_fd == -1) {
			fprintf(stderr, "Can't open output file \"%s\": %s\n",
					bin_filename, strerror(errno));
			return EXIT_FAILURE;
		}
	}

	if (write(bin_fd, dataptr, sizeof(*dataptr) * datasize) !=
			sizeof(*dataptr) * datasize) {
		fprintf(stderr, "write() failed: %s\n", strerror(errno));
		return EXIT_FAILURE;
	}

	ret = close(bin_fd);

	return ret;
}
