/*
 * Copyright International Business Machines Corp., 2006, 2007
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * Authors: Oliver Lohmann <oliloh@de.ibm.com>
 *	    Drake Dowsett <dowsett@de.ibm.com>
 * Contact: Andreas Arnez <anrez@de.ibm.com>
 */

/* TODO Compare data before writing it. This implies that the volume
 * parameters are compared first: size, alignment, name, type, ...,
 * this is the same, compare the data. Volume deletion is deffered
 * until the difference has been found out.
 */

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#define __USE_GNU
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/ioctl.h>

#include <libubi.h>
#include <pfiflash.h>

#include <mtd/ubi-user.h>	/* FIXME Is this ok here? */
#include <mtd/mtd-user.h>

#include "pfiflash_error.h"
#include "ubimirror.h"
#include "error.h"
#include "reader.h"
#include "example_ubi.h"
#include "bootenv.h"

/* ubi-header.h and crc32.h needed for CRC checking */
#include <mtd/ubi-media.h>	/* FIXME Is this ok here? */
#include "crc32.h"

#define ubi_unused __attribute__((unused))

#define COMPARE_BUFFER_SIZE 2048

#define DEFAULT_DEV_PATTERN    "/dev/ubi%d"
#define DEFAULT_VOL_PATTERN    "/dev/ubi%d_%d"

static const char copyright [] ubi_unused =
	"Copyright International Business Machines Corp., 2006, 2007";

/* simply clear buffer, then write into front of it */
#define EBUF(fmt...)							\
		snprintf(err_buf, err_buf_size, fmt);

/* make a history of buffer and then prepend something in front */
#define EBUF_PREPEND(fmt)						\
	do {								\
		int EBUF_HISTORY_LENGTH = strlen(err_buf);		\
		char EBUF_HISTORY[EBUF_HISTORY_LENGTH + 1];		\
		strncpy(EBUF_HISTORY, err_buf, EBUF_HISTORY_LENGTH + 1);\
		EBUF(fmt ": %s", EBUF_HISTORY);				\
	} while (0)

/* An array of PDD function pointers indexed by the algorithm. */
static pdd_func_t pdd_funcs[PDD_HANDLING_NUM]  =
	{
		&bootenv_pdd_keep,
		&bootenv_pdd_merge,
		&bootenv_pdd_overwrite
	};

typedef enum ubi_update_process_t {
	UBI_REMOVE = 0,
	UBI_WRITE,
	UBI_COMPARE,
} ubi_update_process_t;


/**
 * skip_raw_volumes - reads data from pfi to advance fp past raw block
 * @pfi:	fp to pfi data
 * @pfi_raws:	header information
 *
 * Error handling):
 *	when early EOF in pfi data
 *	- returns -PFIFLASH_ERR_EOF, err_buf matches text to err
 *	when file I/O error
 *	- returns -PFIFLASH_ERR_FIO, err_buf matches text to err
 **/
static int
skip_raw_volumes(FILE* pfi, list_t pfi_raws,
		  char* err_buf, size_t err_buf_size)
{
	int rc;
	void *i;
	list_t ptr;

	if (is_empty(pfi_raws))
		return 0;

	rc = 0;
	foreach(i, ptr, pfi_raws) {
		size_t j;
		pfi_raw_t raw;

		raw = (pfi_raw_t)i;
		for(j = 0; j < raw->data_size; j++) {
			int c;

			c = fgetc(pfi);
			if (c == EOF)
				rc = -PFIFLASH_ERR_EOF;
			else if (ferror(pfi))
				rc = -PFIFLASH_ERR_FIO;

			if (rc != 0)
				goto err;
		}
	}

 err:
	EBUF("%s", PFIFLASH_ERRSTR[-rc]);
	return rc;
}


/**
 * my_ubi_mkvol - wraps the ubi_mkvol functions and impl. bootenv update hook
 * @devno:	UBI device number.
 * @s:		Current seqnum.
 * @u:		Information about the UBI volume from the PFI.
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 *	when UBI system couldn't create a volume
 *	- returns -PFIFLASH_ERR_UBI_MKVOL, err_buf matches text to err
 **/
static int
my_ubi_mkvol(int devno, int s, pfi_ubi_t u,
	     char *err_buf, size_t err_buf_size)
{
	int rc, type;
	char path[PATH_MAX];
	libubi_t ulib;
	struct ubi_mkvol_request req;

	rc = 0;
	ulib = NULL;

	log_msg("[ ubimkvol id=%d, size=%d, data_size=%d, type=%d, "
		"alig=%d, nlen=%d, name=%s",
		u->ids[s], u->size, u->data_size, u->type, u->alignment,
		strnlen(u->names[s], PFI_UBI_VOL_NAME_LEN), u->names[s]);

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	switch (u->type) {
	case pfi_ubi_static:
		type = UBI_STATIC_VOLUME; break;
	case pfi_ubi_dynamic:
	default:
		type = UBI_DYNAMIC_VOLUME;
	}

	snprintf(path, PATH_MAX, DEFAULT_DEV_PATTERN, devno);

	req.vol_id = u->ids[s];
	req.alignment = u->alignment;
	req.bytes = u->size;
	req.vol_type = type;
	req.name = u->names[s];

	rc = ubi_mkvol(ulib, path, &req);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_UBI_MKVOL;
		EBUF(PFIFLASH_ERRSTR[-rc], u->ids[s]);
		goto err;
	}

 err:
	if (ulib != NULL)
		libubi_close(ulib);

	return rc;
}


/**
 * my_ubi_rmvol - a wrapper around the UBI library function ubi_rmvol
 * @devno	UBI device number
 * @id		UBI volume id to remove
 *
 * If the volume does not exist, the function will return success.
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 *	when UBI system couldn't update (truncate) a volume
 *	- returns -PFIFLASH_ERR_UBI_VOL_UPDATE, err_buf matches text to err
 *	when UBI system couldn't remove a volume
 *	- returns -PFIFLASH_ERR_UBI_RMVOL, err_buf matches text to err
 **/
static int
my_ubi_rmvol(int devno, uint32_t id,
	     char *err_buf, size_t err_buf_size)
{
	int rc, fd;
	char path[PATH_MAX];
	libubi_t ulib;

	rc = 0;
	ulib = NULL;

	log_msg("[ ubirmvol id=%d", id);

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id);

	/* truncate whether it exist or not */
	fd = open(path, O_RDWR);
	if (fd < 0) {
		libubi_close(ulib);
		return 0;	/* not existent, return 0 */
	}

	rc = ubi_update_start(ulib, fd, 0);
	close(fd);
	if (rc < 0) {
		rc = -PFIFLASH_ERR_UBI_VOL_UPDATE;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;	/* if EBUSY than empty device, continue */
	}

	snprintf(path, PATH_MAX, DEFAULT_DEV_PATTERN, devno);

	rc = ubi_rmvol(ulib, path, id);
	if (rc != 0) {
#ifdef DEBUG
		int rc_old = rc;
		dbg_msg("Remove UBI volume %d returned with error: %d "
			"errno=%d", id, rc_old, errno);
#endif

		rc = -PFIFLASH_ERR_UBI_RMVOL;
		EBUF(PFIFLASH_ERRSTR[-rc], id);

		/* TODO Define a ubi_rmvol return value which says
		 * sth like EUBI_NOSUCHDEV. In this case, a failed
		 * operation is acceptable. Everything else has to be
		 * classified as real error. But talk to Andreas Arnez
		 * before defining something odd...
		 */
		/* if ((errno == EINVAL) || (errno == ENODEV))
		   return 0; */ /* currently it is EINVAL or ENODEV */

		goto err;
	}

 err:
	if (ulib != NULL)
		libubi_close(ulib);

	return rc;
}


/**
 * read_bootenv_volume - reads the current bootenv data from id into be_old
 * @devno	UBI device number
 * @id		UBI volume id to remove
 * @bootenv_old	to hold old boot_env data
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 *	when UBI system couldn't open a volume to read
 *	- returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err
 *	when couldn't read bootenv data
 *	- returns -PFIFLASH_ERR_BOOTENV_READ, err_buf matches text to err
 **/
static int
read_bootenv_volume(int devno, uint32_t id, bootenv_t bootenv_old,
		    char *err_buf, size_t err_buf_size)
{
	int rc;
	FILE* fp_in;
	char path[PATH_MAX];
	libubi_t ulib;

	rc = 0;
	fp_in = NULL;
	ulib = NULL;

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id);

	fp_in = fopen(path, "r");
	if (!fp_in) {
		rc = -PFIFLASH_ERR_UBI_VOL_FOPEN;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}

	log_msg("[ reading old bootenvs ...");

	/* Save old bootenvs for reference */
	rc = bootenv_read(fp_in, bootenv_old, BOOTENV_MAXSIZE);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_READ;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

 err:
	if (fp_in)
		fclose(fp_in);
	if (ulib)
		libubi_close(ulib);

	return rc;
}


/**
 * write_bootenv_volume - writes data from PFI file int to bootenv UBI volume
 * @devno	UBI device number
 * @id		UBI volume id
 * @bootend_old	old PDD data from machine
 * @pdd_f	function to handle PDD with
 * @fp_in	new pdd data contained in PFI
 * @fp_in_size	data size of new pdd data in PFI
 * @pfi_crc	crc value from PFI header
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 *	when bootenv can't be created
 *	- returns -PFIFLASH_ERR_BOOTENV_CREATE, err_buf matches text to err
 *	when bootenv can't be read
 *	- returns -PFIFLASH_ERR_BOOTENV_READ, err_buf matches text to err
 *	when PDD handling function returns and error
 *	- passes rc and err_buf data
 *	when CRC check fails
 *	- returns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err
 *	when bootenv can't be resized
 *	- returns -PFIFLASH_ERR_BOOTENV_SIZE, err_buf matches text to err
 *	when UBI system couldn't open a volume
 *	- returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err
 *	when couldn't write bootenv data
 *	- returns -PFIFLASH_ERR_BOOTENV_WRITE, err_buf matches text to err
 **/
static int
write_bootenv_volume(int devno, uint32_t id, bootenv_t bootenv_old,
		     pdd_func_t pdd_f, FILE* fp_in, size_t fp_in_size,
		     uint32_t pfi_crc,
		     char *err_buf, size_t err_buf_size)
{
	int rc, warnings, fd_out;
	uint32_t crc;
	char path[PATH_MAX];
	size_t update_size;
	FILE *fp_out;
	bootenv_t bootenv_new, bootenv_res;
	libubi_t ulib;

	rc = 0;
	warnings = 0;
	crc = 0;
	update_size = 0;
	fp_out = NULL;
	bootenv_new = NULL;
	bootenv_res = NULL;
	ulib = NULL;

	log_msg("[ ubiupdatevol bootenv id=%d, fp_in=%p", id, fp_in);

	/* Workflow:
	 * 1. Apply PDD operation and get the size of the returning
	 *    bootenv_res section. Without the correct size it wouldn't
	 *    be possible to call UBI update vol.
	 * 2. Call UBI update vol
	 * 3. Get FILE* to vol dev
	 * 4. Write to FILE*
	 */

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	rc = bootenv_create(&bootenv_new);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		EBUF(PFIFLASH_ERRSTR[-rc], " 'new'");
		goto err;
	}

	rc = bootenv_create(&bootenv_res);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		EBUF(PFIFLASH_ERRSTR[-rc], " 'res'");
		goto err;
	}

	rc = bootenv_read_crc(fp_in, bootenv_new, fp_in_size, &crc);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_READ;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	} else if (crc != pfi_crc) {
		rc = -PFIFLASH_ERR_CRC_CHECK;
		EBUF(PFIFLASH_ERRSTR[-rc], pfi_crc, crc);
		goto err;
	}

	rc = pdd_f(bootenv_old, bootenv_new, &bootenv_res, &warnings,
		   err_buf, err_buf_size);
	if (rc != 0) {
		EBUF_PREPEND("handling PDD");
		goto err;
	}
	else if (warnings)
		/* TODO do something with warnings */
		dbg_msg("A warning in the PDD operation occured: %d",
			warnings);

	rc = bootenv_size(bootenv_res, &update_size);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_SIZE;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id);

	fd_out = open(path, O_RDWR);
	if (fd_out < 0) {
		rc = -PFIFLASH_ERR_UBI_VOL_FOPEN;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}
	fp_out = fdopen(fd_out, "r+");
	if (!fp_out) {
		rc = -PFIFLASH_ERR_UBI_VOL_FOPEN;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}
	rc = ubi_update_start(ulib, fd_out, update_size);
	if (rc < 0) {
		rc = -PFIFLASH_ERR_UBI_VOL_UPDATE;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}

	rc = bootenv_write(fp_out, bootenv_res);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_WRITE;
		EBUF(PFIFLASH_ERRSTR[-rc], devno, id);
		goto err;
	}

 err:
	if (ulib != NULL)
		libubi_close(ulib);
	if (bootenv_new != NULL)
		bootenv_destroy(&bootenv_new);
	if (bootenv_res != NULL)
		bootenv_destroy(&bootenv_res);
	if (fp_out)
		fclose(fp_out);

	return rc;
}


/**
 * write_normal_volume - writes data from PFI file int to regular UBI volume
 * @devno	UBI device number
 * @id		UBI volume id
 * @update_size	size of data stream
 * @fp_in	PFI data file pointer
 * @pfi_crc	CRC data from PFI header
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 *	when UBI system couldn't open a volume
 *	- returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err
 *	when unexpected EOF is encountered
 *	- returns -PFIFLASH_ERR_EOF, err_buf matches text to err
 *	when file I/O error
 *	- returns -PFIFLASH_ERR_FIO, err_buf matches text to err
 *	when CRC check fails
 *	- retruns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err
 **/
static int
write_normal_volume(int devno, uint32_t id, size_t update_size, FILE* fp_in,
		    uint32_t pfi_crc,
		    char *err_buf, size_t err_buf_size)
{
	int rc, fd_out;
	uint32_t crc, crc32_table[256];
	char path[PATH_MAX];
	size_t bytes_left;
	FILE* fp_out;
	libubi_t ulib;

	rc = 0;
	crc = UBI_CRC32_INIT;
	bytes_left = update_size;
	fp_out = NULL;
	ulib = NULL;

	log_msg("[ ubiupdatevol id=%d, update_size=%d fp_in=%p",
		id, update_size, fp_in);

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id);

	fd_out = open(path, O_RDWR);
	if (fd_out < 0) {
		rc = -PFIFLASH_ERR_UBI_VOL_FOPEN;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}
	fp_out = fdopen(fd_out, "r+");
	if (!fp_out) {
		rc = -PFIFLASH_ERR_UBI_VOL_FOPEN;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}
	rc = ubi_update_start(ulib, fd_out, update_size);
	if (rc < 0) {
		rc = -PFIFLASH_ERR_UBI_VOL_UPDATE;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}

	init_crc32_table(crc32_table);
	while (bytes_left) {
		char buf[1024];
		size_t to_rw = sizeof buf > bytes_left ?
			bytes_left : sizeof buf;
		if (fread(buf, 1, to_rw, fp_in) != to_rw) {
			rc = -PFIFLASH_ERR_EOF;
			EBUF("%s", PFIFLASH_ERRSTR[-rc]);
			goto err;
		}
		crc = clc_crc32(crc32_table, crc, buf, to_rw);
		if (fwrite(buf, 1, to_rw, fp_out) != to_rw) {
			rc = -PFIFLASH_ERR_FIO;
			EBUF("%s", PFIFLASH_ERRSTR[-rc]);
			goto err;
		}
		bytes_left -= to_rw;
	}

	if (crc != pfi_crc) {
		rc = -PFIFLASH_ERR_CRC_CHECK;
		EBUF(PFIFLASH_ERRSTR[-rc], pfi_crc, crc);
		goto err;
	}

 err:
	if (fp_out)
		fclose(fp_out);
	if (ulib)
		libubi_close(ulib);

	return rc;
}

static int compare_bootenv(FILE *fp_pfi, FILE **fp_flash, uint32_t ids_size,
		uint32_t data_size, pdd_func_t pdd_f, char *err_buf,
		size_t err_buf_size)
{
	int rc, warnings = 0;
	unsigned int i;
	bootenv_t bootenv_pfi, bootenv_res = NULL, bootenv_flash = NULL;

	rc = bootenv_create(&bootenv_pfi);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		goto err;
	}

	rc = bootenv_create(&bootenv_res);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		goto err;
	}

	rc = bootenv_read(fp_pfi, bootenv_pfi, data_size);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_READ;
		goto err;
	}

	for (i = 0; i < ids_size; i++) {
		rc = bootenv_create(&bootenv_flash);
		if (rc != 0) {
			rc = -PFIFLASH_ERR_BOOTENV_CREATE;
			goto err;
		}

		rc = bootenv_read(fp_flash[i], bootenv_flash, BOOTENV_MAXSIZE);
		if (rc != 0) {
			rc = -PFIFLASH_ERR_BOOTENV_READ;
			goto err;
		}

		rc = pdd_f(bootenv_flash, bootenv_pfi, &bootenv_res,
				&warnings, err_buf, err_buf_size);
		if (rc != 0) {
			rc = -PFIFLASH_ERR_PDD_UNKNOWN;
			goto err;
		}

		rc = bootenv_compare(bootenv_flash, bootenv_res);
		if (rc > 0) {
			rc = -PFIFLASH_CMP_DIFF;
			goto err;
		} else if (rc < 0) {
			rc = -PFIFLASH_ERR_COMPARE;
			goto err;
		}

		bootenv_destroy(&bootenv_flash);
		bootenv_flash = NULL;
	}

err:
	if (bootenv_pfi)
		bootenv_destroy(&bootenv_pfi);
	if (bootenv_res)
		bootenv_destroy(&bootenv_res);
	if (bootenv_flash)
		bootenv_destroy(&bootenv_flash);

	return rc;
}

static int compare_data(FILE *fp_pfi, FILE **fp_flash, uint32_t ids_size,
		uint32_t bytes_left)
{
	unsigned int i;
	size_t read_bytes, rc = 0;
	char buf_pfi[COMPARE_BUFFER_SIZE];
	char *buf_flash[ids_size];

	for (i = 0; i < ids_size; i++) {
		buf_flash[i] = malloc(COMPARE_BUFFER_SIZE);
		if (!buf_flash[i])
			return -PFIFLASH_ERR_COMPARE;
	}

	while (bytes_left) {
		if (bytes_left > COMPARE_BUFFER_SIZE)
			read_bytes = COMPARE_BUFFER_SIZE;
		else
			read_bytes = bytes_left;

		rc = fread(buf_pfi, 1, read_bytes, fp_pfi);
		if (rc != read_bytes) {
			rc = -PFIFLASH_ERR_COMPARE;
			goto err;
		}

		for (i = 0; i < ids_size; i++) {
			rc = fread(buf_flash[i], 1, read_bytes, fp_flash[i]);
			if (rc != read_bytes) {
				rc = -PFIFLASH_CMP_DIFF;
				goto err;
			}

			rc = memcmp(buf_pfi, buf_flash[i], read_bytes);
			if (rc != 0) {
				rc = -PFIFLASH_CMP_DIFF;
				goto err;
			}
		}

		bytes_left -= read_bytes;
	}

err:
	for (i = 0; i < ids_size; i++)
		free(buf_flash[i]);

	return rc;
}

static int compare_volumes(int devno, pfi_ubi_t u, FILE *fp_pfi,
		pdd_func_t pdd_f, char *err_buf, size_t err_buf_size)
{
	int rc, is_bootenv = 0;
	unsigned int i;
	char path[PATH_MAX];
	libubi_t ulib = NULL;
	FILE *fp_flash[u->ids_size];

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		goto err;
	}

	for (i = 0; i < u->ids_size; i++) {
		if (u->ids[i] == EXAMPLE_BOOTENV_VOL_ID_1 ||
		    u->ids[i] == EXAMPLE_BOOTENV_VOL_ID_2)
			is_bootenv = 1;

		snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, u->ids[i]);

		fp_flash[i] = fopen(path, "r");
		if (fp_flash[i] == NULL) {
			rc = -PFIFLASH_ERR_UBI_OPEN;
			goto err;
		}
	}

	if (is_bootenv)
		rc = compare_bootenv(fp_pfi, fp_flash, u->ids_size,
				u->data_size, pdd_f, err_buf, err_buf_size);
	else
		rc = compare_data(fp_pfi, fp_flash, u->ids_size, u->data_size);

err:
	if (rc < 0)
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);

	for (i = 0; i < u->ids_size; i++)
		fclose(fp_flash[i]);
	if (ulib)
		libubi_close(ulib);

	return rc;
}

static int
erase_mtd_region(FILE* file_p, int start, int length)
{
	int rc, fd;
	erase_info_t erase;
	mtd_info_t mtdinfo;
	loff_t offset = start;
	loff_t end = offset + length;

	fd = fileno(file_p);
	if (fd < 0)
		return -PFIFLASH_ERR_MTD_ERASE;

	rc = ioctl(fd, MEMGETINFO, &mtdinfo);
	if (rc)
		return -PFIFLASH_ERR_MTD_ERASE;

	/* check for bad blocks in case of NAND flash */
	if (mtdinfo.type == MTD_NANDFLASH) {
		while (offset < end) {
			rc = ioctl(fd, MEMGETBADBLOCK, &offset);
			if (rc > 0) {
				return -PFIFLASH_ERR_MTD_ERASE;
			}

			offset += mtdinfo.erasesize;
		}
	}

	erase.start = start;
	erase.length = length;

	rc = ioctl(fd, MEMERASE, &erase);
	if (rc) {
		return -PFIFLASH_ERR_MTD_ERASE;
	}

	return rc;
}

/**
 * process_raw_volumes - writes the raw sections of the PFI data
 * @pfi		PFI data file pointer
 * @pfi_raws	list of PFI raw headers
 * @rawdev	device to use to write raw data
 *
 * Error handling:
 *	when early EOF in PFI data
 *	- returns -PFIFLASH_ERR_EOF, err_buf matches text to err
 *	when file I/O error
 *	- returns -PFIFLASH_ERR_FIO, err_buf matches text to err
 *	when CRC check fails
 *	- returns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err
 *	when opening MTD device fails
 *	- reutrns -PFIFLASH_ERR_MTD_OPEN, err_buf matches text to err
 *	when closing MTD device fails
 *	- returns -PFIFLASH_ERR_MTD_CLOSE, err_buf matches text to err
 **/
static int
process_raw_volumes(FILE* pfi, list_t pfi_raws, const char* rawdev,
		    char* err_buf, size_t err_buf_size)
{
	int rc;
	char *pfi_data;
	void *i;
	uint32_t crc, crc32_table[256];
	size_t j, k;
	FILE* mtd = NULL;
	list_t ptr;

	if (is_empty(pfi_raws))
		return 0;

	if (rawdev == NULL)
		return 0;

	rc = 0;

	pfi_data = NULL;

	log_msg("[ rawupdate dev=%s", rawdev);

	crc = UBI_CRC32_INIT;
	init_crc32_table(crc32_table);

	/* most likely only one element in list, but just in case */
	foreach(i, ptr, pfi_raws) {
		pfi_raw_t r = (pfi_raw_t)i;

		/* read in pfi data */
		if (pfi_data != NULL)
			free(pfi_data);
		pfi_data = malloc(r->data_size * sizeof(char));
		for (j = 0; j < r->data_size; j++) {
			int c = fgetc(pfi);
			if (c == EOF) {
				rc = -PFIFLASH_ERR_EOF;
				EBUF("%s", PFIFLASH_ERRSTR[-rc]);
				goto err;
			} else if (ferror(pfi)) {
				rc = -PFIFLASH_ERR_FIO;
				EBUF("%s", PFIFLASH_ERRSTR[-rc]);
				goto err;
			}
			pfi_data[j] = (char)c;
		}
		crc = clc_crc32(crc32_table, crc, pfi_data, r->data_size);

		/* check crc */
		if (crc != r->crc) {
			rc = -PFIFLASH_ERR_CRC_CHECK;
			EBUF(PFIFLASH_ERRSTR[-rc], r->crc, crc);
			goto err;
		}

		/* open device */
		mtd = fopen(rawdev, "r+");
		if (mtd == NULL) {
			rc = -PFIFLASH_ERR_MTD_OPEN;
			EBUF(PFIFLASH_ERRSTR[-rc], rawdev);
			goto err;
		}

		for (j = 0; j < r->starts_size; j++) {
			rc = erase_mtd_region(mtd, r->starts[j], r->data_size);
			if (rc) {
				EBUF("%s", PFIFLASH_ERRSTR[-rc]);
				goto err;
			}

			fseek(mtd, r->starts[j], SEEK_SET);
			for (k = 0; k < r->data_size; k++) {
				int c = fputc((int)pfi_data[k], mtd);
				if (c == EOF) {
					fclose(mtd);
					rc = -PFIFLASH_ERR_EOF;
					EBUF("%s", PFIFLASH_ERRSTR[-rc]);
					goto err;
				}
				if ((char)c != pfi_data[k]) {
					fclose(mtd);
					rc = -1;
					goto err;
				}
			}
		}
		rc = fclose(mtd);
		mtd = NULL;
		if (rc != 0) {
			rc = -PFIFLASH_ERR_MTD_CLOSE;
			EBUF(PFIFLASH_ERRSTR[-rc], rawdev);
			goto err;
		}
	}

 err:
	if (mtd != NULL)
		fclose(mtd);
	if (pfi_data != NULL)
		free(pfi_data);
	return rc;
}


/**
 * erase_unmapped_ubi_volumes - skip volumes provided by PFI file, clear rest
 * @devno	UBI device number
 * @pfi_ubis	list of UBI header data
 *
 * Error handling:
 *	when UBI id is out of bounds
 *	- returns -PFIFLASH_ERR_UBI_VID_OOB, err_buf matches text to err
 *	when UBI volume can't be removed
 *	- passes rc, prepends err_buf with contextual aid
 **/
static int
erase_unmapped_ubi_volumes(int devno, list_t pfi_ubis,
			   char *err_buf, size_t err_buf_size)
{
	int rc;
	uint8_t ubi_volumes[PFI_UBI_MAX_VOLUMES];
	size_t i;
	list_t ptr;
	pfi_ubi_t u;

	rc = 0;

	for (i = 0; i < PFI_UBI_MAX_VOLUMES; i++)
		ubi_volumes[i] = 1;

	foreach(u, ptr, pfi_ubis) {
		/* iterate over each vol_id */
		for(i = 0; i < u->ids_size; i++) {
			if (u->ids[i] >= PFI_UBI_MAX_VOLUMES) {
				rc = -PFIFLASH_ERR_UBI_VID_OOB;
				EBUF(PFIFLASH_ERRSTR[-rc], u->ids[i]);
				goto err;
			}
			/* remove from removal list */
			ubi_volumes[u->ids[i]] = 0;
		}
	}

	for (i = 0; i < PFI_UBI_MAX_VOLUMES; i++) {
		if (ubi_volumes[i]) {
			rc = my_ubi_rmvol(devno, i, err_buf, err_buf_size);
			if (rc != 0) {
				EBUF_PREPEND("remove volume failed");
				goto err;
			}
		}
	}

 err:
	return rc;
}


/**
 * process_ubi_volumes - delegate tasks regarding UBI volumes
 * @pfi			PFI data file pointer
 * @seqnum		sequence number
 * @pfi_ubis		list of UBI header data
 * @bootenv_old		storage for current system PDD
 * @pdd_f		function to handle PDD
 * @ubi_update_process	whether reading or writing
 *
 * Error handling:
 *	when and unknown ubi_update_process is given
 *	- returns -PFIFLASH_ERR_UBI_UNKNOWN, err_buf matches text to err
 *	otherwise
 *	- passes rc and err_buf
 **/
static int
process_ubi_volumes(FILE* pfi, int seqnum, list_t pfi_ubis,
		    bootenv_t bootenv_old, pdd_func_t pdd_f,
		    ubi_update_process_t ubi_update_process,
		    char *err_buf, size_t err_buf_size)
{
	int rc;
	pfi_ubi_t u;
	list_t ptr;

	rc = 0;

	foreach(u, ptr, pfi_ubis) {
		int s = seqnum;

		if (s > ((int)u->ids_size - 1))
			s = 0; /* per default use the first */
		u->curr_seqnum = s;

		switch (ubi_update_process) {
		case UBI_REMOVE:
			/* TODO are all these "EXAMPLE" vars okay? */
			if ((u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_1) ||
			    (u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_2)) {
				rc = read_bootenv_volume(EXAMPLE_UBI_DEVICE,
							 u->ids[s], bootenv_old,
							 err_buf, err_buf_size);
				/* it's okay if there is no bootenv
				 * we're going to write one */
				if ((rc == -PFIFLASH_ERR_UBI_VOL_FOPEN) ||
				    (rc == -PFIFLASH_ERR_BOOTENV_READ))
					rc = 0;
				if (rc != 0)
					goto err;
			}

			rc = my_ubi_rmvol(EXAMPLE_UBI_DEVICE, u->ids[s],
					  err_buf, err_buf_size);
			if (rc != 0)
				goto err;

			break;
		case UBI_WRITE:
			rc = my_ubi_mkvol(EXAMPLE_UBI_DEVICE, s, u,
					  err_buf, err_buf_size);
			if (rc != 0) {
				EBUF_PREPEND("creating volume");
				goto err;
			}

			if ((u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_1) ||
			    (u->ids[s] == EXAMPLE_BOOTENV_VOL_ID_2)) {
				rc = write_bootenv_volume(EXAMPLE_UBI_DEVICE,
							  u->ids[s],
							  bootenv_old, pdd_f,
							  pfi,
							  u->data_size,
							  u->crc,
							  err_buf,
							  err_buf_size);
				if (rc != 0)
					EBUF_PREPEND("bootenv volume");
			} else {
				rc = write_normal_volume(EXAMPLE_UBI_DEVICE,
							 u->ids[s],
							 u->data_size, pfi,
							 u->crc,
							 err_buf,
							 err_buf_size);
				if (rc != 0)
					EBUF_PREPEND("normal volume");
			}
			if (rc != 0)
				goto err;

			break;
		case UBI_COMPARE:
			rc = compare_volumes(EXAMPLE_UBI_DEVICE, u, pfi, pdd_f,
					err_buf, err_buf_size);
			if (rc != 0) {
				EBUF_PREPEND("compare volume");
				goto err;
			}

			break;
		default:
			rc = -PFIFLASH_ERR_UBI_UNKNOWN;
			EBUF("%s", PFIFLASH_ERRSTR[-rc]);
			goto err;
		}
	}

 err:
	return rc;
}


/**
 * mirror_ubi_volumes - mirror redundant pairs of volumes
 * @devno	UBI device number
 * @pfi_ubis	list of PFI header data
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 **/
static int
mirror_ubi_volumes(uint32_t devno, list_t pfi_ubis,
		   char *err_buf, size_t err_buf_size)
{
	int rc;
	uint32_t j;
	list_t ptr;
	pfi_ubi_t i;
	libubi_t ulib;

	rc = 0;
	ulib = NULL;

	log_msg("[ mirror ...");

	ulib = libubi_open();
	if (ulib == NULL) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	/**
	 * Execute all mirror operations on redundant groups.
	 * Create a volume within a redundant group if it does
	 * not exist already (this is a precondition of
	 * ubimirror).
	 */
	foreach(i, ptr, pfi_ubis) {
		for (j = 0; j < i->ids_size; j++) {
			/* skip self-match */
			if (i->ids[j] == i->ids[i->curr_seqnum])
				continue;

			rc = my_ubi_rmvol(devno, i->ids[j],
					  err_buf, err_buf_size);
			if (rc != 0)
				goto err;

			rc = my_ubi_mkvol(devno, j, i,
					  err_buf, err_buf_size);
			if (rc != 0)
				goto err;
		}
	}

	foreach(i, ptr, pfi_ubis) {
		rc = ubimirror(devno, i->curr_seqnum, i->ids, i->ids_size,
			       err_buf, err_buf_size);
		if (rc != 0)
			goto err;
	}


 err:
	if (ulib != NULL)
		libubi_close(ulib);

	return rc;
}


/**
 * pfiflash_with_options - exposed func to flash memory with a PFI file
 * @pfi			PFI data file pointer
 * @complete		flag to erase unmapped volumes
 * @seqnum		sequence number
 * @compare		flag to compare
 * @pdd_handling	method to handle pdd (keep, merge, overwrite...)
 *
 * Error handling:
 *	when bootenv can't be created
 *	- returns -PFIFLASH_ERR_BOOTENV_CREATE, err_buf matches text to err
 *	when PFI headers can't be read, or
 *	when fail to skip raw sections, or
 *	when error occurs while processing raw volumes, or
 *	when fail to erase unmapped UBI vols, or
 *	when error occurs while processing UBI volumes, or
 *	when error occurs while mirroring UBI volumes
 *	- passes rc, prepends err_buf with contextual aid
 **/
int
pfiflash_with_options(FILE* pfi, int complete, int seqnum, int compare,
		  pdd_handling_t pdd_handling, const char* rawdev,
		  char *err_buf, size_t err_buf_size)
{
	int rc;
	bootenv_t bootenv;
	pdd_func_t pdd_f;

	if (pfi == NULL)
		return -EINVAL;

	rc = 0;
	pdd_f = NULL;

	/* If the user didnt specify a seqnum we start per default
	 * with the index 0 */
	int curr_seqnum = seqnum < 0 ? 0 : seqnum;

	list_t pfi_raws   = mk_empty(); /* list of raw sections from a pfi */
	list_t pfi_ubis   = mk_empty(); /* list of ubi sections from a pfi */

	rc = bootenv_create(&bootenv);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		EBUF(PFIFLASH_ERRSTR[-rc], "");
		goto err;
	}

	rc = read_pfi_headers(&pfi_raws, &pfi_ubis, pfi, err_buf, err_buf_size);
	if (rc != 0) {
		EBUF_PREPEND("reading PFI header");
		goto err;
	}

	if (rawdev == NULL || compare)
		rc = skip_raw_volumes(pfi, pfi_raws, err_buf, err_buf_size);
	else
		rc = process_raw_volumes(pfi, pfi_raws, rawdev, err_buf,
					 err_buf_size);
	if (rc != 0) {
		EBUF_PREPEND("handling raw section");
		goto err;
	}

	if (complete && !compare) {
		rc = erase_unmapped_ubi_volumes(EXAMPLE_UBI_DEVICE, pfi_ubis,
						err_buf, err_buf_size);
		if (rc != 0) {
			EBUF_PREPEND("deleting unmapped UBI volumes");
			goto err;
		}
	}

	if (((int)pdd_handling >= 0) &&
	    (pdd_handling < PDD_HANDLING_NUM))
		pdd_f = pdd_funcs[pdd_handling];
	else {
		rc = -PFIFLASH_ERR_PDD_UNKNOWN;
		EBUF("%s", PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	if (!compare) {
		rc = process_ubi_volumes(pfi, curr_seqnum, pfi_ubis, bootenv,
				pdd_f, UBI_REMOVE, err_buf, err_buf_size);
		if (rc != 0) {
			EBUF_PREPEND("removing UBI volumes");
			goto err;
		}

		rc = process_ubi_volumes(pfi, curr_seqnum, pfi_ubis, bootenv,
				pdd_f, UBI_WRITE, err_buf, err_buf_size);
		if  (rc != 0) {
			EBUF_PREPEND("writing UBI volumes");
			goto err;
		}

		if (seqnum < 0) { /* mirror redundant pairs */
			rc = mirror_ubi_volumes(EXAMPLE_UBI_DEVICE, pfi_ubis,
					err_buf, err_buf_size);
			if (rc != 0) {
				EBUF_PREPEND("mirroring UBI volumes");
				goto err;
			}
		}
	} else {
		/* only compare volumes, don't alter the content */
		rc = process_ubi_volumes(pfi, curr_seqnum, pfi_ubis, bootenv,
				pdd_f, UBI_COMPARE, err_buf, err_buf_size);

		if (rc == -PFIFLASH_CMP_DIFF)
			/* update is necessary, return positive value */
			rc = 1;

		if (rc < 0) {
			EBUF_PREPEND("comparing UBI volumes");
			goto err;
		}
	}

 err:
	pfi_raws = remove_all((free_func_t)&free_pfi_raw, pfi_raws);
	pfi_ubis = remove_all((free_func_t)&free_pfi_ubi, pfi_ubis);
	bootenv_destroy(&bootenv);
	return rc;
}


/**
 * pfiflash - passes to pfiflash_with_options
 * @pfi			PFI data file pointer
 * @complete		flag to erase unmapped volumes
 * @seqnum		sequence number
 * @pdd_handling	method to handle pdd (keep, merge, overwrite...)
 **/
int
pfiflash(FILE* pfi, int complete, int seqnum, pdd_handling_t pdd_handling,
		char *err_buf, size_t err_buf_size)
{
	return pfiflash_with_options(pfi, complete, seqnum, 0, pdd_handling,
				 NULL, err_buf, err_buf_size);
}
