/*
 * Copyright (c) International Business Machines Corp., 2006
 *
 * 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.
 */

/*
 * An utility to update UBI volumes.
 *
 * Authors: Frank Haverkamp
 *          Joshua W. Boyer
 *          Artem Bityutskiy
 */

#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

#include <libubi.h>
#include "common.h"

#define PROGRAM_VERSION "1.2"
#define PROGRAM_NAME    "ubiupdatevol"

struct args {
	int truncate;
	const char *node;
	const char *img;
	/* For deprecated -d and -B options handling */
	char dev_name[256];
	int size;
	int use_stdin;
};

static struct args args;

static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
			 " - a tool to write data to UBI volumes.";

static const char *optionsstr =
"-t, --truncate             truncate volume (wipe it out)\n"
"-s, --size=<bytes>         bytes in input, if not reading from file\n"
"-h, --help                 print help message\n"
"-V, --version              print program version";

static const char *usage =
"Usage: " PROGRAM_NAME " <UBI volume node file name> [-t] [-s <size>] [-h] [-V] [--truncate]\n"
"\t\t\t[--size=<size>] [--help] [--version] <image file>\n\n"
"Example 1: " PROGRAM_NAME " /dev/ubi0_1 fs.img - write file \"fs.img\" to UBI volume /dev/ubi0_1\n"
"Example 2: " PROGRAM_NAME " /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1";

struct option long_options[] = {
	{ .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' },
	{ .name = "help",     .has_arg = 0, .flag = NULL, .val = 'h' },
	{ .name = "version",  .has_arg = 0, .flag = NULL, .val = 'V' },
	{ .name = "size",     .has_arg = 1, .flag = NULL, .val = 's' },
	{ NULL, 0, NULL, 0}
};

static int parse_opt(int argc, char * const argv[])
{
	while (1) {
		int key;
		char *endp;

		key = getopt_long(argc, argv, "ts:h?V", long_options, NULL);
		if (key == -1)
			break;

		switch (key) {
		case 't':
			args.truncate = 1;
			break;

		case 's':
			args.size = strtoul(optarg, &endp, 0);
			if (*endp != '\0' || endp == optarg || args.size < 0)
				return errmsg("bad size: " "\"%s\"", optarg);
			break;

		case 'h':
		case '?':
			fprintf(stderr, "%s\n\n", doc);
			fprintf(stderr, "%s\n\n", usage);
			fprintf(stderr, "%s\n", optionsstr);
			exit(EXIT_SUCCESS);

		case 'V':
			fprintf(stderr, "%s\n", PROGRAM_VERSION);
			exit(EXIT_SUCCESS);

		case ':':
			return errmsg("parameter is missing");

		default:
			fprintf(stderr, "Use -h for help\n");
			return -1;
		}
	}

	if (optind == argc)
		return errmsg("UBI device name was not specified (use -h for help)");
	else if (optind != argc - 2 && !args.truncate)
		return errmsg("specify UBI device name and image file name as first 2 "
			      "parameters (use -h for help)");

	args.node = argv[optind];
	args.img  = argv[optind + 1];

	if (args.img && args.truncate)
		return errmsg("You can't truncate and specify an image (use -h for help)");

	if (args.img && !args.truncate) {
		if (strcmp(args.img, "-") == 0)
			args.use_stdin = 1;
		if (args.use_stdin && !args.size)
			return errmsg("file size must be specified if input is stdin");
	}

	return 0;
}

static int truncate_volume(libubi_t libubi)
{
	int err, fd;

	fd = open(args.node, O_RDWR);
	if (fd == -1)
		return sys_errmsg("cannot open \"%s\"", args.node);

	err = ubi_update_start(libubi, fd, 0);
	if (err) {
		sys_errmsg("cannot truncate volume \"%s\"", args.node);
		close(fd);
		return -1;
	}

	close(fd);
	return 0;
}

static int ubi_write(int fd, const void *buf, int len)
{
	int ret;

	while (len) {
		ret = write(fd, buf, len);
		if (ret < 0) {
			if (errno == EINTR) {
				warnmsg("do not interrupt me!");
				continue;
			}
			return sys_errmsg("cannot write %d bytes to volume \"%s\"",
					  len, args.node);
		}

		if (ret == 0)
			return errmsg("cannot write %d bytes to volume \"%s\"", len, args.node);

		len -= ret;
		buf += ret;
	}

	return 0;
}

static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info)
{
	int err, fd, ifd;
	long long bytes;
	char *buf;

	buf = malloc(vol_info->leb_size);
	if (!buf)
		return errmsg("cannot allocate %d bytes of memory", vol_info->leb_size);

	if (!args.size) {
		struct stat st;
		err = stat(args.img, &st);
		if (err < 0) {
			errmsg("stat failed on \"%s\"", args.img);
			goto out_free;
		}

		bytes = st.st_size;
	} else
		bytes = args.size;

	if (bytes > vol_info->rsvd_bytes) {
		errmsg("\"%s\" (size %lld) will not fit volume \"%s\" (size %lld)",
		       args.img, bytes, args.node, vol_info->rsvd_bytes);
		goto out_free;
	}

	fd = open(args.node, O_RDWR);
	if (fd == -1) {
		sys_errmsg("cannot open UBI volume \"%s\"", args.node);
		goto out_free;
	}

	if (args.use_stdin)
		ifd = STDIN_FILENO;
	else {
		ifd = open(args.img, O_RDONLY);
		if (ifd == -1) {
			sys_errmsg("cannot open \"%s\"", args.img);
			goto out_close1;
		}
	}

	err = ubi_update_start(libubi, fd, bytes);
	if (err) {
		sys_errmsg("cannot start volume \"%s\" update", args.node);
		goto out_close;
	}

	while (bytes) {
		int ret, to_copy = vol_info->leb_size;

		if (to_copy > bytes)
			to_copy = bytes;

		ret = read(ifd, buf, to_copy);
		if (ret <= 0) {
			if (errno == EINTR) {
				warnmsg("do not interrupt me!");
				continue;
			} else {
				sys_errmsg("cannot read %d bytes from \"%s\"",
						to_copy, args.img);
				goto out_close;
			}
		}

		err = ubi_write(fd, buf, ret);
		if (err)
			goto out_close;
		bytes -= ret;
	}

	close(ifd);
	close(fd);
	free(buf);
	return 0;

out_close:
	close(ifd);
out_close1:
	close(fd);
out_free:
	free(buf);
	return -1;
}

int main(int argc, char * const argv[])
{
	int err;
	libubi_t libubi;
	struct ubi_vol_info vol_info;

	err = parse_opt(argc, argv);
	if (err)
		return -1;

	libubi = libubi_open();
	if (!libubi) {
		if (errno == 0)
			return errmsg("UBI is not present in the system");
		else
			return errmsg("cannot open libubi");
	}

	err = ubi_probe_node(libubi, args.node);
	if (err == 1) {
		errmsg("\"%s\" is an UBI device node, not an UBI volume node",
		       args.node);
		goto out_libubi;
	} else if (err < 0) {
		if (errno == ENODEV)
			errmsg("\"%s\" is not an UBI volume node", args.node);
		else
			sys_errmsg("error while probing \"%s\"", args.node);
		goto out_libubi;
	}

	err = ubi_get_vol_info(libubi, args.node, &vol_info);
	if (err) {
		sys_errmsg("cannot get information about UBI volume \"%s\"",
			   args.node);
		goto out_libubi;
	}

	if (args.truncate)
		err = truncate_volume(libubi);
	else
		err = update_volume(libubi, &vol_info);
	if (err)
		goto out_libubi;

	libubi_close(libubi);
	return 0;

out_libubi:
	libubi_close(libubi);
	return -1;
}
