// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2000-2010
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2008
 * Guennadi Liakhovetski, DENX Software Engineering, lg@denx.de.
 */

#define _GNU_SOURCE

#include <compiler.h>
#include <env.h>
#include <errno.h>
#include <env_flags.h>
#include <fcntl.h>
#include <libgen.h>
#include <linux/fs.h>
#include <linux/stringify.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#ifdef MTD_OLD
# include <stdint.h>
# include <linux/mtd/mtd.h>
#else
# define  __user	/* nothing */
# include <mtd/mtd-user.h>
#endif

#include <mtd/ubi-user.h>

#include "fw_env_private.h"
#include "fw_env.h"

struct env_opts default_opts = {
#ifdef CONFIG_FILE
	.config_file = CONFIG_FILE
#endif
};

#define DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))

#define min(x, y) ({				\
	typeof(x) _min1 = (x);			\
	typeof(y) _min2 = (y);			\
	(void) (&_min1 == &_min2);		\
	_min1 < _min2 ? _min1 : _min2; })

struct envdev_s {
	const char *devname;		/* Device name */
	long long devoff;		/* Device offset */
	ulong env_size;			/* environment size */
	ulong erase_size;		/* device erase size */
	ulong env_sectors;		/* number of environment sectors */
	uint8_t mtd_type;		/* type of the MTD device */
	int is_ubi;			/* set if we use UBI volume */
};

static struct envdev_s envdevices[2] = {
	{
		.mtd_type = MTD_ABSENT,
	}, {
		.mtd_type = MTD_ABSENT,
	},
};

static int dev_current;

#define DEVNAME(i)    envdevices[(i)].devname
#define DEVOFFSET(i)  envdevices[(i)].devoff
#define ENVSIZE(i)    envdevices[(i)].env_size
#define DEVESIZE(i)   envdevices[(i)].erase_size
#define ENVSECTORS(i) envdevices[(i)].env_sectors
#define DEVTYPE(i)    envdevices[(i)].mtd_type
#define IS_UBI(i)     envdevices[(i)].is_ubi

#define CUR_ENVSIZE ENVSIZE(dev_current)

static unsigned long usable_envsize;
#define ENV_SIZE      usable_envsize

struct env_image_single {
	uint32_t crc;		/* CRC32 over data bytes    */
	char data[];
};

struct env_image_redundant {
	uint32_t crc;		/* CRC32 over data bytes    */
	unsigned char flags;	/* active or obsolete */
	char data[];
};

enum flag_scheme {
	FLAG_NONE,
	FLAG_BOOLEAN,
	FLAG_INCREMENTAL,
};

struct environment {
	void *image;
	uint32_t *crc;
	unsigned char *flags;
	char *data;
	enum flag_scheme flag_scheme;
};

static struct environment environment = {
	.flag_scheme = FLAG_NONE,
};

static int have_redund_env;

#define DEFAULT_ENV_INSTANCE_STATIC
#include <env_default.h>

#define UBI_DEV_START "/dev/ubi"
#define UBI_SYSFS "/sys/class/ubi"
#define UBI_VOL_NAME_PATT "ubi%d_%d"

static int is_ubi_devname(const char *devname)
{
	return !strncmp(devname, UBI_DEV_START, sizeof(UBI_DEV_START) - 1);
}

static int ubi_check_volume_sysfs_name(const char *volume_sysfs_name,
				       const char *volname)
{
	char path[256];
	FILE *file;
	char *name;
	int ret;

	strcpy(path, UBI_SYSFS "/");
	strcat(path, volume_sysfs_name);
	strcat(path, "/name");

	file = fopen(path, "r");
	if (!file)
		return -1;

	ret = fscanf(file, "%ms", &name);
	fclose(file);
	if (ret <= 0 || !name) {
		fprintf(stderr,
			"Failed to read from file %s, ret = %d, name = %s\n",
			path, ret, name);
		return -1;
	}

	if (!strcmp(name, volname)) {
		free(name);
		return 0;
	}
	free(name);

	return -1;
}

static int ubi_get_volnum_by_name(int devnum, const char *volname)
{
	DIR *sysfs_ubi;
	struct dirent *dirent;
	int ret;
	int tmp_devnum;
	int volnum;

	sysfs_ubi = opendir(UBI_SYSFS);
	if (!sysfs_ubi)
		return -1;

#ifdef DEBUG
	fprintf(stderr, "Looking for volume name \"%s\"\n", volname);
#endif

	while (1) {
		dirent = readdir(sysfs_ubi);
		if (!dirent)
			return -1;

		ret = sscanf(dirent->d_name, UBI_VOL_NAME_PATT,
			     &tmp_devnum, &volnum);
		if (ret == 2 && devnum == tmp_devnum) {
			if (ubi_check_volume_sysfs_name(dirent->d_name,
							volname) == 0)
				return volnum;
		}
	}

	return -1;
}

static int ubi_get_devnum_by_devname(const char *devname)
{
	int devnum;
	int ret;

	ret = sscanf(devname + sizeof(UBI_DEV_START) - 1, "%d", &devnum);
	if (ret != 1)
		return -1;

	return devnum;
}

static const char *ubi_get_volume_devname(const char *devname,
					  const char *volname)
{
	char *volume_devname;
	int volnum;
	int devnum;
	int ret;

	devnum = ubi_get_devnum_by_devname(devname);
	if (devnum < 0)
		return NULL;

	volnum = ubi_get_volnum_by_name(devnum, volname);
	if (volnum < 0)
		return NULL;

	ret = asprintf(&volume_devname, "%s_%d", devname, volnum);
	if (ret < 0)
		return NULL;

#ifdef DEBUG
	fprintf(stderr, "Found ubi volume \"%s:%s\" -> %s\n",
		devname, volname, volume_devname);
#endif

	return volume_devname;
}

static void ubi_check_dev(unsigned int dev_id)
{
	char *devname = (char *)DEVNAME(dev_id);
	char *pname;
	const char *volname = NULL;
	const char *volume_devname;

	if (!is_ubi_devname(DEVNAME(dev_id)))
		return;

	IS_UBI(dev_id) = 1;

	for (pname = devname; *pname != '\0'; pname++) {
		if (*pname == ':') {
			*pname = '\0';
			volname = pname + 1;
			break;
		}
	}

	if (volname) {
		/* Let's find real volume device name */
		volume_devname = ubi_get_volume_devname(devname, volname);
		if (!volume_devname) {
			fprintf(stderr, "Didn't found ubi volume \"%s\"\n",
				volname);
			return;
		}

		free(devname);
		DEVNAME(dev_id) = volume_devname;
	}
}

static int ubi_update_start(int fd, int64_t bytes)
{
	if (ioctl(fd, UBI_IOCVOLUP, &bytes))
		return -1;
	return 0;
}

static int ubi_read(int fd, void *buf, size_t count)
{
	ssize_t ret;

	while (count > 0) {
		ret = read(fd, buf, count);
		if (ret > 0) {
			count -= ret;
			buf += ret;

			continue;
		}

		if (ret == 0) {
			/*
			 * Happens in case of too short volume data size. If we
			 * return error status we will fail it will be treated
			 * as UBI device error.
			 *
			 * Leave catching this error to CRC check.
			 */
			fprintf(stderr, "Warning: end of data on ubi volume\n");
			return 0;
		} else if (errno == EBADF) {
			/*
			 * Happens in case of corrupted volume. The same as
			 * above, we cannot return error now, as we will still
			 * be able to successfully write environment later.
			 */
			fprintf(stderr, "Warning: corrupted volume?\n");
			return 0;
		} else if (errno == EINTR) {
			continue;
		}

		fprintf(stderr, "Cannot read %u bytes from ubi volume, %s\n",
			(unsigned int)count, strerror(errno));
		return -1;
	}

	return 0;
}

static int ubi_write(int fd, const void *buf, size_t count)
{
	ssize_t ret;

	while (count > 0) {
		ret = write(fd, buf, count);
		if (ret <= 0) {
			if (ret < 0 && errno == EINTR)
				continue;

			fprintf(stderr, "Cannot write %u bytes to ubi volume\n",
				(unsigned int)count);
			return -1;
		}

		count -= ret;
		buf += ret;
	}

	return 0;
}

static int flash_io(int mode);
static int parse_config(struct env_opts *opts);

#if defined(CONFIG_FILE)
static int get_config(char *);
#endif

static char *skip_chars(char *s)
{
	for (; *s != '\0'; s++) {
		if (isblank(*s) || *s == '=')
			return s;
	}
	return NULL;
}

static char *skip_blanks(char *s)
{
	for (; *s != '\0'; s++) {
		if (!isblank(*s))
			return s;
	}
	return NULL;
}

/*
 * s1 is either a simple 'name', or a 'name=value' pair.
 * s2 is a 'name=value' pair.
 * If the names match, return the value of s2, else NULL.
 */
static char *envmatch(char *s1, char *s2)
{
	if (s1 == NULL || s2 == NULL)
		return NULL;

	while (*s1 == *s2++)
		if (*s1++ == '=')
			return s2;
	if (*s1 == '\0' && *(s2 - 1) == '=')
		return s2;
	return NULL;
}

/**
 * Search the environment for a variable.
 * Return the value, if found, or NULL, if not found.
 */
char *fw_getenv(char *name)
{
	char *env, *nxt;

	for (env = environment.data; *env; env = nxt + 1) {
		char *val;

		for (nxt = env; *nxt; ++nxt) {
			if (nxt >= &environment.data[ENV_SIZE]) {
				fprintf(stderr, "## Error: "
					"environment not terminated\n");
				return NULL;
			}
		}
		val = envmatch(name, env);
		if (!val)
			continue;
		return val;
	}
	return NULL;
}

/*
 * Search the default environment for a variable.
 * Return the value, if found, or NULL, if not found.
 */
char *fw_getdefenv(char *name)
{
	char *env, *nxt;

	for (env = default_environment; *env; env = nxt + 1) {
		char *val;

		for (nxt = env; *nxt; ++nxt) {
			if (nxt >= &default_environment[ENV_SIZE]) {
				fprintf(stderr, "## Error: "
					"default environment not terminated\n");
				return NULL;
			}
		}
		val = envmatch(name, env);
		if (!val)
			continue;
		return val;
	}
	return NULL;
}

/*
 * Print the current definition of one, or more, or all
 * environment variables
 */
int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts)
{
	int i, rc = 0;

	if (value_only && argc != 1) {
		fprintf(stderr,
			"## Error: `-n'/`--noheader' option requires exactly one argument\n");
		return -1;
	}

	if (!opts)
		opts = &default_opts;

	if (fw_env_open(opts))
		return -1;

	if (argc == 0) {	/* Print all env variables  */
		char *env, *nxt;
		for (env = environment.data; *env; env = nxt + 1) {
			for (nxt = env; *nxt; ++nxt) {
				if (nxt >= &environment.data[ENV_SIZE]) {
					fprintf(stderr, "## Error: "
						"environment not terminated\n");
					return -1;
				}
			}

			printf("%s\n", env);
		}
		fw_env_close(opts);
		return 0;
	}

	for (i = 0; i < argc; ++i) {	/* print a subset of env variables */
		char *name = argv[i];
		char *val = NULL;

		val = fw_getenv(name);
		if (!val) {
			fprintf(stderr, "## Error: \"%s\" not defined\n", name);
			rc = -1;
			continue;
		}

		if (value_only) {
			puts(val);
			break;
		}

		printf("%s=%s\n", name, val);
	}

	fw_env_close(opts);

	return rc;
}

int fw_env_flush(struct env_opts *opts)
{
	if (!opts)
		opts = &default_opts;

	/*
	 * Update CRC
	 */
	*environment.crc = crc32(0, (uint8_t *) environment.data, ENV_SIZE);

	/* write environment back to flash */
	if (flash_io(O_RDWR)) {
		fprintf(stderr, "Error: can't write fw_env to flash\n");
		return -1;
	}

	return 0;
}

/*
 * Set/Clear a single variable in the environment.
 * This is called in sequence to update the environment
 * in RAM without updating the copy in flash after each set
 */
int fw_env_write(char *name, char *value)
{
	int len;
	char *env, *nxt;
	char *oldval = NULL;
	int deleting, creating, overwriting;

	/*
	 * search if variable with this name already exists
	 */
	for (nxt = env = environment.data; *env; env = nxt + 1) {
		for (nxt = env; *nxt; ++nxt) {
			if (nxt >= &environment.data[ENV_SIZE]) {
				fprintf(stderr, "## Error: "
					"environment not terminated\n");
				errno = EINVAL;
				return -1;
			}
		}
		oldval = envmatch(name, env);
		if (oldval)
			break;
	}

	deleting = (oldval && !(value && strlen(value)));
	creating = (!oldval && (value && strlen(value)));
	overwriting = (oldval && (value && strlen(value)));

	/* check for permission */
	if (deleting) {
		if (env_flags_validate_varaccess(name,
		    ENV_FLAGS_VARACCESS_PREVENT_DELETE)) {
			printf("Can't delete \"%s\"\n", name);
			errno = EROFS;
			return -1;
		}
	} else if (overwriting) {
		if (env_flags_validate_varaccess(name,
		    ENV_FLAGS_VARACCESS_PREVENT_OVERWR)) {
			printf("Can't overwrite \"%s\"\n", name);
			errno = EROFS;
			return -1;
		} else if (env_flags_validate_varaccess(name,
			   ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR)) {
			const char *defval = fw_getdefenv(name);

			if (defval == NULL)
				defval = "";
			if (strcmp(oldval, defval)
			    != 0) {
				printf("Can't overwrite \"%s\"\n", name);
				errno = EROFS;
				return -1;
			}
		}
	} else if (creating) {
		if (env_flags_validate_varaccess(name,
		    ENV_FLAGS_VARACCESS_PREVENT_CREATE)) {
			printf("Can't create \"%s\"\n", name);
			errno = EROFS;
			return -1;
		}
	} else
		/* Nothing to do */
		return 0;

	if (deleting || overwriting) {
		if (*++nxt == '\0') {
			*env = '\0';
		} else {
			for (;;) {
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

	/* Delete only ? */
	if (!value || !strlen(value))
		return 0;

	/*
	 * Append new definition at the end
	 */
	for (env = environment.data; *env || *(env + 1); ++env)
		;
	if (env > environment.data)
		++env;
	/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > CUR_ENVSIZE - (env-environment)
	 */
	len = strlen(name) + 2;
	/* add '=' for first arg, ' ' for all others */
	len += strlen(value) + 1;

	if (len > (&environment.data[ENV_SIZE] - env)) {
		fprintf(stderr,
			"Error: environment overflow, \"%s\" deleted\n", name);
		return -1;
	}

	while ((*env = *name++) != '\0')
		env++;
	*env = '=';
	while ((*++env = *value++) != '\0')
		;

	/* end is marked with double '\0' */
	*++env = '\0';

	return 0;
}

/*
 * Deletes or sets environment variables. Returns -1 and sets errno error codes:
 * 0	  - OK
 * EINVAL - need at least 1 argument
 * EROFS  - certain variables ("ethaddr", "serial#") cannot be
 *	    modified or deleted
 *
 */
int fw_env_set(int argc, char *argv[], struct env_opts *opts)
{
	int i;
	size_t len;
	char *name, **valv;
	char *oldval;
	char *value = NULL;
	int valc;
	int ret;

	if (!opts)
		opts = &default_opts;

	if (argc < 1) {
		fprintf(stderr, "## Error: variable name missing\n");
		errno = EINVAL;
		return -1;
	}

	if (fw_env_open(opts)) {
		fprintf(stderr, "Error: environment not initialized\n");
		return -1;
	}

	name = argv[0];
	valv = argv + 1;
	valc = argc - 1;

	if (env_flags_validate_env_set_params(name, valv, valc) < 0) {
		fw_env_close(opts);
		return -1;
	}

	len = 0;
	for (i = 0; i < valc; ++i) {
		char *val = valv[i];
		size_t val_len = strlen(val);

		if (value)
			value[len - 1] = ' ';
		oldval = value;
		value = realloc(value, len + val_len + 1);
		if (!value) {
			fprintf(stderr,
				"Cannot malloc %zu bytes: %s\n",
				len, strerror(errno));
			free(oldval);
			return -1;
		}

		memcpy(value + len, val, val_len);
		len += val_len;
		value[len++] = '\0';
	}

	fw_env_write(name, value);

	free(value);

	ret = fw_env_flush(opts);
	fw_env_close(opts);

	return ret;
}

/*
 * Parse  a file  and configure the u-boot variables.
 * The script file has a very simple format, as follows:
 *
 * Each line has a couple with name, value:
 * <white spaces>variable_name<white spaces>variable_value
 *
 * Both variable_name and variable_value are interpreted as strings.
 * Any character after <white spaces> and before ending \r\n is interpreted
 * as variable's value (no comment allowed on these lines !)
 *
 * Comments are allowed if the first character in the line is #
 *
 * Returns -1 and sets errno error codes:
 * 0	  - OK
 * -1     - Error
 */
int fw_parse_script(char *fname, struct env_opts *opts)
{
	FILE *fp;
	char *line = NULL;
	size_t linesize = 0;
	char *name;
	char *val;
	int lineno = 0;
	int len;
	int ret = 0;

	if (!opts)
		opts = &default_opts;

	if (fw_env_open(opts)) {
		fprintf(stderr, "Error: environment not initialized\n");
		return -1;
	}

	if (strcmp(fname, "-") == 0)
		fp = stdin;
	else {
		fp = fopen(fname, "r");
		if (fp == NULL) {
			fprintf(stderr, "I cannot open %s for reading\n",
				fname);
			return -1;
		}
	}

	while ((len = getline(&line, &linesize, fp)) != -1) {
		lineno++;

		/*
		 * Read a whole line from the file. If the line is not
		 * terminated, reports an error and exit.
		 */
		if (line[len - 1] != '\n') {
			fprintf(stderr,
				"Line %d not correctly terminated\n",
				lineno);
			ret = -1;
			break;
		}

		/* Drop ending line feed / carriage return */
		line[--len] = '\0';
		if (len && line[len - 1] == '\r')
			line[--len] = '\0';

		/* Skip comment or empty lines */
		if (len == 0 || line[0] == '#')
			continue;

		/*
		 * Search for variable's name remove leading whitespaces
		 */
		name = skip_blanks(line);
		if (!name)
			continue;

		/* The first white space is the end of variable name */
		val = skip_chars(name);
		len = strlen(name);
		if (val) {
			*val++ = '\0';
			if ((val - name) < len)
				val = skip_blanks(val);
			else
				val = NULL;
		}
#ifdef DEBUG
		fprintf(stderr, "Setting %s : %s\n",
			name, val ? val : " removed");
#endif

		if (env_flags_validate_type(name, val) < 0) {
			ret = -1;
			break;
		}

		/*
		 * If there is an error setting a variable,
		 * try to save the environment and returns an error
		 */
		if (fw_env_write(name, val)) {
			fprintf(stderr,
				"fw_env_write returns with error : %s\n",
				strerror(errno));
			ret = -1;
			break;
		}

	}
	free(line);

	/* Close file if not stdin */
	if (strcmp(fname, "-") != 0)
		fclose(fp);

	ret |= fw_env_flush(opts);

	fw_env_close(opts);

	return ret;
}

/**
 * environment_end() - compute offset of first byte right after environment
 * @dev - index of enviroment buffer
 * Return:
 *  device offset of first byte right after environment
 */
off_t environment_end(int dev)
{
	/* environment is block aligned */
	return DEVOFFSET(dev) + ENVSECTORS(dev) * DEVESIZE(dev);
}

/*
 * Test for bad block on NAND, just returns 0 on NOR, on NAND:
 * 0	- block is good
 * > 0	- block is bad
 * < 0	- failed to test
 */
static int flash_bad_block(int fd, uint8_t mtd_type, loff_t blockstart)
{
	if (mtd_type == MTD_NANDFLASH) {
		int badblock = ioctl(fd, MEMGETBADBLOCK, &blockstart);

		if (badblock < 0) {
			perror("Cannot read bad block mark");
			return badblock;
		}

		if (badblock) {
#ifdef DEBUG
			fprintf(stderr, "Bad block at 0x%llx, skipping\n",
				(unsigned long long)blockstart);
#endif
			return badblock;
		}
	}

	return 0;
}

/*
 * Read data from flash at an offset into a provided buffer. On NAND it skips
 * bad blocks but makes sure it stays within ENVSECTORS (dev) starting from
 * the DEVOFFSET (dev) block. On NOR the loop is only run once.
 */
static int flash_read_buf(int dev, int fd, void *buf, size_t count,
			  off_t offset)
{
	size_t blocklen;	/* erase / write length - one block on NAND,
				   0 on NOR */
	size_t processed = 0;	/* progress counter */
	size_t readlen = count;	/* current read length */
	off_t block_seek;	/* offset inside the current block to the start
				   of the data */
	loff_t blockstart;	/* running start of the current block -
				   MEMGETBADBLOCK needs 64 bits */
	int rc;

	blockstart = (offset / DEVESIZE(dev)) * DEVESIZE(dev);

	/* Offset inside a block */
	block_seek = offset - blockstart;

	if (DEVTYPE(dev) == MTD_NANDFLASH) {
		/*
		 * NAND: calculate which blocks we are reading. We have
		 * to read one block at a time to skip bad blocks.
		 */
		blocklen = DEVESIZE(dev);

		/* Limit to one block for the first read */
		if (readlen > blocklen - block_seek)
			readlen = blocklen - block_seek;
	} else {
		blocklen = 0;
	}

	/* This only runs once on NOR flash */
	while (processed < count) {
		rc = flash_bad_block(fd, DEVTYPE(dev), blockstart);
		if (rc < 0)	/* block test failed */
			return -1;

		if (blockstart + block_seek + readlen > environment_end(dev)) {
			/* End of range is reached */
			fprintf(stderr, "Too few good blocks within range\n");
			return -1;
		}

		if (rc) {	/* block is bad */
			blockstart += blocklen;
			continue;
		}

		/*
		 * If a block is bad, we retry in the next block at the same
		 * offset - see env/nand.c::writeenv()
		 */
		lseek(fd, blockstart + block_seek, SEEK_SET);

		rc = read(fd, buf + processed, readlen);
		if (rc != readlen) {
			fprintf(stderr, "Read error on %s: %s\n",
				DEVNAME(dev), strerror(errno));
			return -1;
		}
#ifdef DEBUG
		fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n",
			rc, (unsigned long long)blockstart + block_seek,
			DEVNAME(dev));
#endif
		processed += readlen;
		readlen = min(blocklen, count - processed);
		block_seek = 0;
		blockstart += blocklen;
	}

	return processed;
}

/*
 * Write count bytes from begin of environment, but stay within
 * ENVSECTORS(dev) sectors of
 * DEVOFFSET (dev). Similar to the read case above, on NOR and dataflash we
 * erase and write the whole data at once.
 */
static int flash_write_buf(int dev, int fd, void *buf, size_t count)
{
	void *data;
	struct erase_info_user erase;
	size_t blocklen;	/* length of NAND block / NOR erase sector */
	size_t erase_len;	/* whole area that can be erased - may include
				   bad blocks */
	size_t erasesize;	/* erase / write length - one block on NAND,
				   whole area on NOR */
	size_t processed = 0;	/* progress counter */
	size_t write_total;	/* total size to actually write - excluding
				   bad blocks */
	off_t erase_offset;	/* offset to the first erase block (aligned)
				   below offset */
	off_t block_seek;	/* offset inside the erase block to the start
				   of the data */
	loff_t blockstart;	/* running start of the current block -
				   MEMGETBADBLOCK needs 64 bits */
	int rc;

	/*
	 * For mtd devices only offset and size of the environment do matter
	 */
	if (DEVTYPE(dev) == MTD_ABSENT) {
		blocklen = count;
		erase_len = blocklen;
		blockstart = DEVOFFSET(dev);
		block_seek = 0;
		write_total = blocklen;
	} else {
		blocklen = DEVESIZE(dev);

		erase_offset = DEVOFFSET(dev);

		/* Maximum area we may use */
		erase_len = environment_end(dev) - erase_offset;

		blockstart = erase_offset;

		/* Offset inside a block */
		block_seek = DEVOFFSET(dev) - erase_offset;

		/*
		 * Data size we actually write: from the start of the block
		 * to the start of the data, then count bytes of data, and
		 * to the end of the block
		 */
		write_total = ((block_seek + count + blocklen - 1) /
			       blocklen) * blocklen;
	}

	/*
	 * Support data anywhere within erase sectors: read out the complete
	 * area to be erased, replace the environment image, write the whole
	 * block back again.
	 */
	if (write_total > count) {
		data = malloc(erase_len);
		if (!data) {
			fprintf(stderr,
				"Cannot malloc %zu bytes: %s\n",
				erase_len, strerror(errno));
			return -1;
		}

		rc = flash_read_buf(dev, fd, data, write_total, erase_offset);
		if (write_total != rc)
			return -1;

#ifdef DEBUG
		fprintf(stderr, "Preserving data ");
		if (block_seek != 0)
			fprintf(stderr, "0x%x - 0x%lx", 0, block_seek - 1);
		if (block_seek + count != write_total) {
			if (block_seek != 0)
				fprintf(stderr, " and ");
			fprintf(stderr, "0x%lx - 0x%lx",
				(unsigned long)block_seek + count,
				(unsigned long)write_total - 1);
		}
		fprintf(stderr, "\n");
#endif
		/* Overwrite the old environment */
		memcpy(data + block_seek, buf, count);
	} else {
		/*
		 * We get here, iff offset is block-aligned and count is a
		 * multiple of blocklen - see write_total calculation above
		 */
		data = buf;
	}

	if (DEVTYPE(dev) == MTD_NANDFLASH) {
		/*
		 * NAND: calculate which blocks we are writing. We have
		 * to write one block at a time to skip bad blocks.
		 */
		erasesize = blocklen;
	} else {
		erasesize = erase_len;
	}

	erase.length = erasesize;

	/* This only runs once on NOR flash and SPI-dataflash */
	while (processed < write_total) {
		rc = flash_bad_block(fd, DEVTYPE(dev), blockstart);
		if (rc < 0)	/* block test failed */
			return rc;

		if (blockstart + erasesize > environment_end(dev)) {
			fprintf(stderr, "End of range reached, aborting\n");
			return -1;
		}

		if (rc) {	/* block is bad */
			blockstart += blocklen;
			continue;
		}

		if (DEVTYPE(dev) != MTD_ABSENT) {
			erase.start = blockstart;
			ioctl(fd, MEMUNLOCK, &erase);
			/* These do not need an explicit erase cycle */
			if (DEVTYPE(dev) != MTD_DATAFLASH)
				if (ioctl(fd, MEMERASE, &erase) != 0) {
					fprintf(stderr,
						"MTD erase error on %s: %s\n",
						DEVNAME(dev), strerror(errno));
					return -1;
				}
		}

		if (lseek(fd, blockstart, SEEK_SET) == -1) {
			fprintf(stderr,
				"Seek error on %s: %s\n",
				DEVNAME(dev), strerror(errno));
			return -1;
		}
#ifdef DEBUG
		fprintf(stderr, "Write 0x%llx bytes at 0x%llx\n",
			(unsigned long long)erasesize,
			(unsigned long long)blockstart);
#endif
		if (write(fd, data + processed, erasesize) != erasesize) {
			fprintf(stderr, "Write error on %s: %s\n",
				DEVNAME(dev), strerror(errno));
			return -1;
		}

		if (DEVTYPE(dev) != MTD_ABSENT)
			ioctl(fd, MEMLOCK, &erase);

		processed += erasesize;
		block_seek = 0;
		blockstart += erasesize;
	}

	if (write_total > count)
		free(data);

	return processed;
}

/*
 * Set obsolete flag at offset - NOR flash only
 */
static int flash_flag_obsolete(int dev, int fd, off_t offset)
{
	int rc;
	struct erase_info_user erase;

	erase.start = DEVOFFSET(dev);
	erase.length = DEVESIZE(dev);
	/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */
	rc = lseek(fd, offset, SEEK_SET);
	if (rc < 0) {
		fprintf(stderr, "Cannot seek to set the flag on %s\n",
			DEVNAME(dev));
		return rc;
	}
	ioctl(fd, MEMUNLOCK, &erase);
	rc = write(fd, &ENV_REDUND_OBSOLETE, sizeof(ENV_REDUND_OBSOLETE));
	ioctl(fd, MEMLOCK, &erase);
	if (rc < 0)
		perror("Could not set obsolete flag");

	return rc;
}

static int flash_write(int fd_current, int fd_target, int dev_target)
{
	int rc;

	switch (environment.flag_scheme) {
	case FLAG_NONE:
		break;
	case FLAG_INCREMENTAL:
		(*environment.flags)++;
		break;
	case FLAG_BOOLEAN:
		*environment.flags = ENV_REDUND_ACTIVE;
		break;
	default:
		fprintf(stderr, "Unimplemented flash scheme %u\n",
			environment.flag_scheme);
		return -1;
	}

#ifdef DEBUG
	fprintf(stderr, "Writing new environment at 0x%llx on %s\n",
		DEVOFFSET(dev_target), DEVNAME(dev_target));
#endif

	if (IS_UBI(dev_target)) {
		if (ubi_update_start(fd_target, CUR_ENVSIZE) < 0)
			return 0;
		return ubi_write(fd_target, environment.image, CUR_ENVSIZE);
	}

	rc = flash_write_buf(dev_target, fd_target, environment.image,
			     CUR_ENVSIZE);
	if (rc < 0)
		return rc;

	if (environment.flag_scheme == FLAG_BOOLEAN) {
		/* Have to set obsolete flag */
		off_t offset = DEVOFFSET(dev_current) +
		    offsetof(struct env_image_redundant, flags);
#ifdef DEBUG
		fprintf(stderr,
			"Setting obsolete flag in environment at 0x%llx on %s\n",
			DEVOFFSET(dev_current), DEVNAME(dev_current));
#endif
		flash_flag_obsolete(dev_current, fd_current, offset);
	}

	return 0;
}

static int flash_read(int fd)
{
	int rc;

	if (IS_UBI(dev_current)) {
		DEVTYPE(dev_current) = MTD_ABSENT;

		return ubi_read(fd, environment.image, CUR_ENVSIZE);
	}

	rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE,
			    DEVOFFSET(dev_current));
	if (rc != CUR_ENVSIZE)
		return -1;

	return 0;
}

static int flash_open_tempfile(const char **dname, const char **target_temp)
{
	char *dup_name = strdup(DEVNAME(dev_current));
	char *temp_name = NULL;
	int rc = -1;

	if (!dup_name)
		return -1;

	*dname = dirname(dup_name);
	if (!*dname)
		goto err;

	rc = asprintf(&temp_name, "%s/XXXXXX", *dname);
	if (rc == -1)
		goto err;

	rc = mkstemp(temp_name);
	if (rc == -1) {
		/* fall back to in place write */
		fprintf(stderr,
			"Can't create %s: %s\n", temp_name, strerror(errno));
		free(temp_name);
	} else {
		*target_temp = temp_name;
		/* deliberately leak dup_name as dname /might/ point into
		 * it and we need it for our caller
		 */
		dup_name = NULL;
	}

err:
	if (dup_name)
		free(dup_name);

	return rc;
}

static int flash_io_write(int fd_current)
{
	int fd_target = -1, rc, dev_target;
	const char *dname, *target_temp = NULL;

	if (have_redund_env) {
		/* switch to next partition for writing */
		dev_target = !dev_current;
		/* dev_target: fd_target, erase_target */
		fd_target = open(DEVNAME(dev_target), O_RDWR);
		if (fd_target < 0) {
			fprintf(stderr,
				"Can't open %s: %s\n",
				DEVNAME(dev_target), strerror(errno));
			rc = -1;
			goto exit;
		}
	} else {
		struct stat sb;

		if (fstat(fd_current, &sb) == 0 && S_ISREG(sb.st_mode)) {
			/* if any part of flash_open_tempfile() fails we fall
			 * back to in-place writes
			 */
			fd_target = flash_open_tempfile(&dname, &target_temp);
		}
		dev_target = dev_current;
		if (fd_target == -1)
			fd_target = fd_current;
	}

	rc = flash_write(fd_current, fd_target, dev_target);

	if (fsync(fd_current) && !(errno == EINVAL || errno == EROFS)) {
		fprintf(stderr,
			"fsync failed on %s: %s\n",
			DEVNAME(dev_current), strerror(errno));
	}

	if (fd_current != fd_target) {
		if (fsync(fd_target) &&
		    !(errno == EINVAL || errno == EROFS)) {
			fprintf(stderr,
				"fsync failed on %s: %s\n",
				DEVNAME(dev_current), strerror(errno));
		}

		if (close(fd_target)) {
			fprintf(stderr,
				"I/O error on %s: %s\n",
				DEVNAME(dev_target), strerror(errno));
			rc = -1;
		}

		if (rc >= 0 && target_temp) {
			int dir_fd;

			dir_fd = open(dname, O_DIRECTORY | O_RDONLY);
			if (dir_fd == -1)
				fprintf(stderr,
					"Can't open %s: %s\n",
					dname, strerror(errno));

			if (rename(target_temp, DEVNAME(dev_target))) {
				fprintf(stderr,
					"rename failed %s => %s: %s\n",
					target_temp, DEVNAME(dev_target),
					strerror(errno));
				rc = -1;
			}

			if (dir_fd != -1 && fsync(dir_fd))
				fprintf(stderr,
					"fsync failed on %s: %s\n",
					dname, strerror(errno));

			if (dir_fd != -1 && close(dir_fd))
				fprintf(stderr,
					"I/O error on %s: %s\n",
					dname, strerror(errno));
		}
	}
 exit:
	return rc;
}

static int flash_io(int mode)
{
	int fd_current, rc;

	/* dev_current: fd_current, erase_current */
	fd_current = open(DEVNAME(dev_current), mode);
	if (fd_current < 0) {
		fprintf(stderr,
			"Can't open %s: %s\n",
			DEVNAME(dev_current), strerror(errno));
		return -1;
	}

	if (mode == O_RDWR) {
		rc = flash_io_write(fd_current);
	} else {
		rc = flash_read(fd_current);
	}

	if (close(fd_current)) {
		fprintf(stderr,
			"I/O error on %s: %s\n",
			DEVNAME(dev_current), strerror(errno));
		return -1;
	}

	return rc;
}

/*
 * Prevent confusion if running from erased flash memory
 */
int fw_env_open(struct env_opts *opts)
{
	int crc0, crc0_ok;
	unsigned char flag0;
	void *addr0 = NULL;

	int crc1, crc1_ok;
	unsigned char flag1;
	void *addr1 = NULL;

	int ret;

	struct env_image_single *single;
	struct env_image_redundant *redundant;

	if (!opts)
		opts = &default_opts;

	if (parse_config(opts))	/* should fill envdevices */
		return -EINVAL;

	addr0 = calloc(1, CUR_ENVSIZE);
	if (addr0 == NULL) {
		fprintf(stderr,
			"Not enough memory for environment (%ld bytes)\n",
			CUR_ENVSIZE);
		ret = -ENOMEM;
		goto open_cleanup;
	}

	/* read environment from FLASH to local buffer */
	environment.image = addr0;

	if (have_redund_env) {
		redundant = addr0;
		environment.crc = &redundant->crc;
		environment.flags = &redundant->flags;
		environment.data = redundant->data;
	} else {
		single = addr0;
		environment.crc = &single->crc;
		environment.flags = NULL;
		environment.data = single->data;
	}

	dev_current = 0;
	if (flash_io(O_RDONLY)) {
		ret = -EIO;
		goto open_cleanup;
	}

	crc0 = crc32(0, (uint8_t *)environment.data, ENV_SIZE);

	crc0_ok = (crc0 == *environment.crc);
	if (!have_redund_env) {
		if (!crc0_ok) {
			fprintf(stderr,
				"Warning: Bad CRC, using default environment\n");
			memcpy(environment.data, default_environment,
			       sizeof(default_environment));
		}
	} else {
		flag0 = *environment.flags;

		dev_current = 1;
		addr1 = calloc(1, CUR_ENVSIZE);
		if (addr1 == NULL) {
			fprintf(stderr,
				"Not enough memory for environment (%ld bytes)\n",
				CUR_ENVSIZE);
			ret = -ENOMEM;
			goto open_cleanup;
		}
		redundant = addr1;

		/*
		 * have to set environment.image for flash_read(), careful -
		 * other pointers in environment still point inside addr0
		 */
		environment.image = addr1;
		if (flash_io(O_RDONLY)) {
			ret = -EIO;
			goto open_cleanup;
		}

		/* Check flag scheme compatibility */
		if (DEVTYPE(dev_current) == MTD_NORFLASH &&
		    DEVTYPE(!dev_current) == MTD_NORFLASH) {
			environment.flag_scheme = FLAG_BOOLEAN;
		} else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&
			   DEVTYPE(!dev_current) == MTD_NANDFLASH) {
			environment.flag_scheme = FLAG_INCREMENTAL;
		} else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
			   DEVTYPE(!dev_current) == MTD_DATAFLASH) {
			environment.flag_scheme = FLAG_BOOLEAN;
		} else if (DEVTYPE(dev_current) == MTD_UBIVOLUME &&
			   DEVTYPE(!dev_current) == MTD_UBIVOLUME) {
			environment.flag_scheme = FLAG_INCREMENTAL;
		} else if (DEVTYPE(dev_current) == MTD_ABSENT &&
			   DEVTYPE(!dev_current) == MTD_ABSENT &&
			   IS_UBI(dev_current) == IS_UBI(!dev_current)) {
			environment.flag_scheme = FLAG_INCREMENTAL;
		} else {
			fprintf(stderr, "Incompatible flash types!\n");
			ret = -EINVAL;
			goto open_cleanup;
		}

		crc1 = crc32(0, (uint8_t *)redundant->data, ENV_SIZE);

		crc1_ok = (crc1 == redundant->crc);
		flag1 = redundant->flags;

		if (crc0_ok && !crc1_ok) {
			dev_current = 0;
		} else if (!crc0_ok && crc1_ok) {
			dev_current = 1;
		} else if (!crc0_ok && !crc1_ok) {
			fprintf(stderr,
				"Warning: Bad CRC, using default environment\n");
			memcpy(environment.data, default_environment,
			       sizeof(default_environment));
			dev_current = 0;
		} else {
			switch (environment.flag_scheme) {
			case FLAG_BOOLEAN:
				if (flag0 == ENV_REDUND_ACTIVE &&
				    flag1 == ENV_REDUND_OBSOLETE) {
					dev_current = 0;
				} else if (flag0 == ENV_REDUND_OBSOLETE &&
					   flag1 == ENV_REDUND_ACTIVE) {
					dev_current = 1;
				} else if (flag0 == flag1) {
					dev_current = 0;
				} else if (flag0 == 0xFF) {
					dev_current = 0;
				} else if (flag1 == 0xFF) {
					dev_current = 1;
				} else {
					dev_current = 0;
				}
				break;
			case FLAG_INCREMENTAL:
				if (flag0 == 255 && flag1 == 0)
					dev_current = 1;
				else if ((flag1 == 255 && flag0 == 0) ||
					 flag0 >= flag1)
					dev_current = 0;
				else	/* flag1 > flag0 */
					dev_current = 1;
				break;
			default:
				fprintf(stderr, "Unknown flag scheme %u\n",
					environment.flag_scheme);
				return -1;
			}
		}

		/*
		 * If we are reading, we don't need the flag and the CRC any
		 * more, if we are writing, we will re-calculate CRC and update
		 * flags before writing out
		 */
		if (dev_current) {
			environment.image = addr1;
			environment.crc = &redundant->crc;
			environment.flags = &redundant->flags;
			environment.data = redundant->data;
			free(addr0);
		} else {
			environment.image = addr0;
			/* Other pointers are already set */
			free(addr1);
		}
#ifdef DEBUG
		fprintf(stderr, "Selected env in %s\n", DEVNAME(dev_current));
#endif
	}
	return 0;

 open_cleanup:
	if (addr0)
		free(addr0);

	if (addr1)
		free(addr1);

	return ret;
}

/*
 * Simply free allocated buffer with environment
 */
int fw_env_close(struct env_opts *opts)
{
	if (environment.image)
		free(environment.image);

	environment.image = NULL;

	return 0;
}

static int check_device_config(int dev)
{
	struct stat st;
	int32_t lnum = 0;
	int fd, rc = 0;

	/* Fills in IS_UBI(), converts DEVNAME() with ubi volume name */
	ubi_check_dev(dev);

	fd = open(DEVNAME(dev), O_RDONLY);
	if (fd < 0) {
		fprintf(stderr,
			"Cannot open %s: %s\n", DEVNAME(dev), strerror(errno));
		return -1;
	}

	rc = fstat(fd, &st);
	if (rc < 0) {
		fprintf(stderr, "Cannot stat the file %s\n", DEVNAME(dev));
		goto err;
	}

	if (IS_UBI(dev)) {
		rc = ioctl(fd, UBI_IOCEBISMAP, &lnum);
		if (rc < 0) {
			fprintf(stderr, "Cannot get UBI information for %s\n",
				DEVNAME(dev));
			goto err;
		}
	} else if (S_ISCHR(st.st_mode)) {
		struct mtd_info_user mtdinfo;
		rc = ioctl(fd, MEMGETINFO, &mtdinfo);
		if (rc < 0) {
			fprintf(stderr, "Cannot get MTD information for %s\n",
				DEVNAME(dev));
			goto err;
		}
		if (mtdinfo.type != MTD_NORFLASH &&
		    mtdinfo.type != MTD_NANDFLASH &&
		    mtdinfo.type != MTD_DATAFLASH &&
		    mtdinfo.type != MTD_UBIVOLUME) {
			fprintf(stderr, "Unsupported flash type %u on %s\n",
				mtdinfo.type, DEVNAME(dev));
			goto err;
		}
		DEVTYPE(dev) = mtdinfo.type;
		if (DEVESIZE(dev) == 0)
			/* Assume the erase size is the same as the env-size */
			DEVESIZE(dev) = ENVSIZE(dev);
	} else {
		uint64_t size;
		DEVTYPE(dev) = MTD_ABSENT;
		if (DEVESIZE(dev) == 0)
			/* Assume the erase size to be 512 bytes */
			DEVESIZE(dev) = 0x200;

		/*
		 * Check for negative offsets, treat it as backwards offset
		 * from the end of the block device
		 */
		if (DEVOFFSET(dev) < 0) {
			rc = ioctl(fd, BLKGETSIZE64, &size);
			if (rc < 0) {
				fprintf(stderr,
					"Could not get block device size on %s\n",
					DEVNAME(dev));
				goto err;
			}

			DEVOFFSET(dev) = DEVOFFSET(dev) + size;
#ifdef DEBUG
			fprintf(stderr,
				"Calculated device offset 0x%llx on %s\n",
				DEVOFFSET(dev), DEVNAME(dev));
#endif
		}
	}

	if (ENVSECTORS(dev) == 0)
		/* Assume enough sectors to cover the environment */
		ENVSECTORS(dev) = DIV_ROUND_UP(ENVSIZE(dev), DEVESIZE(dev));

	if (DEVOFFSET(dev) % DEVESIZE(dev) != 0) {
		fprintf(stderr,
			"Environment does not start on (erase) block boundary\n");
		errno = EINVAL;
		return -1;
	}

	if (ENVSIZE(dev) > ENVSECTORS(dev) * DEVESIZE(dev)) {
		fprintf(stderr,
			"Environment does not fit into available sectors\n");
		errno = EINVAL;
		return -1;
	}

 err:
	close(fd);
	return rc;
}

static int parse_config(struct env_opts *opts)
{
	int rc;

	if (!opts)
		opts = &default_opts;

#if defined(CONFIG_FILE)
	/* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */
	if (get_config(opts->config_file)) {
		fprintf(stderr, "Cannot parse config file '%s': %m\n",
			opts->config_file);
		return -1;
	}
#else
	DEVNAME(0) = DEVICE1_NAME;
	DEVOFFSET(0) = DEVICE1_OFFSET;
	ENVSIZE(0) = ENV1_SIZE;

	/* Set defaults for DEVESIZE, ENVSECTORS later once we
	 * know DEVTYPE
	 */
#ifdef DEVICE1_ESIZE
	DEVESIZE(0) = DEVICE1_ESIZE;
#endif
#ifdef DEVICE1_ENVSECTORS
	ENVSECTORS(0) = DEVICE1_ENVSECTORS;
#endif

#ifdef HAVE_REDUND
	DEVNAME(1) = DEVICE2_NAME;
	DEVOFFSET(1) = DEVICE2_OFFSET;
	ENVSIZE(1) = ENV2_SIZE;

	/* Set defaults for DEVESIZE, ENVSECTORS later once we
	 * know DEVTYPE
	 */
#ifdef DEVICE2_ESIZE
	DEVESIZE(1) = DEVICE2_ESIZE;
#endif
#ifdef DEVICE2_ENVSECTORS
	ENVSECTORS(1) = DEVICE2_ENVSECTORS;
#endif
	have_redund_env = 1;
#endif
#endif
	rc = check_device_config(0);
	if (rc < 0)
		return rc;

	if (have_redund_env) {
		rc = check_device_config(1);
		if (rc < 0)
			return rc;

		if (ENVSIZE(0) != ENVSIZE(1)) {
			fprintf(stderr,
				"Redundant environments have unequal size\n");
			return -1;
		}
	}

	usable_envsize = CUR_ENVSIZE - sizeof(uint32_t);
	if (have_redund_env)
		usable_envsize -= sizeof(char);

	return 0;
}

#if defined(CONFIG_FILE)
static int get_config(char *fname)
{
	FILE *fp;
	int i = 0;
	int rc;
	char *line = NULL;
	size_t linesize = 0;
	char *devname;

	fp = fopen(fname, "r");
	if (fp == NULL)
		return -1;

	while (i < 2 && getline(&line, &linesize, fp) != -1) {
		/* Skip comment strings */
		if (line[0] == '#')
			continue;

		rc = sscanf(line, "%ms %lli %lx %lx %lx",
			    &devname,
			    &DEVOFFSET(i),
			    &ENVSIZE(i), &DEVESIZE(i), &ENVSECTORS(i));

		if (rc < 3)
			continue;

		DEVNAME(i) = devname;

		/* Set defaults for DEVESIZE, ENVSECTORS later once we
		 * know DEVTYPE
		 */

		i++;
	}
	free(line);
	fclose(fp);

	have_redund_env = i - 1;
	if (!i) {		/* No valid entries found */
		errno = EINVAL;
		return -1;
	} else
		return 0;
}
#endif
