// SPDX-License-Identifier: GPL-2.0+
/*
 * Based on mkimage.c.
 *
 * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
 */

#include "dumpimage.h"
#include <image.h>
#include <version.h>

static void usage(void);

/* parameters initialized by core will be used by the image type code */
static struct image_tool_params params;

/*
 * dumpimage_extract_subimage -
 *
 * It scans all registered image types,
 * verifies image_header for each supported image type
 * if verification is successful, it extracts the desired file,
 * indexed by pflag, from the image
 *
 * returns negative if input image format does not match with any of
 * supported image types
 */
static int dumpimage_extract_subimage(struct image_type_params *tparams,
		void *ptr, struct stat *sbuf)
{
	int retval = -1;

	if (tparams->verify_header) {
		retval = tparams->verify_header((unsigned char *)ptr,
				sbuf->st_size, &params);
		if (retval != 0) {
			fprintf(stderr, "%s: failed to verify header of %s\n",
				params.cmdname, tparams->name);
			return -1;
		}

		/*
		 * Extract the file from the image
		 * if verify is successful
		 */
		if (tparams->extract_subimage) {
			retval = tparams->extract_subimage(ptr, &params);
			if (retval != 0) {
				fprintf(stderr, "%s: extract_subimage failed for %s\n",
					params.cmdname, tparams->name);
				return -3;
			}
		} else {
			fprintf(stderr,
				"%s: extract_subimage undefined for %s\n",
				params.cmdname, tparams->name);
			return -2;
		}
	}

	return retval;
}

int main(int argc, char **argv)
{
	int opt;
	int ifd = -1;
	struct stat sbuf;
	char *ptr;
	int retval = EXIT_SUCCESS;
	struct image_type_params *tparams = NULL;

	params.cmdname = *argv;

	while ((opt = getopt(argc, argv, "hlo:T:p:V")) != -1) {
		switch (opt) {
		case 'l':
			params.lflag = 1;
			break;
		case 'o':
			params.outfile = optarg;
			params.iflag = 1;
			break;
		case 'T':
			params.type = genimg_get_type_id(optarg);
			if (params.type < 0) {
				fprintf(stderr, "%s: Invalid type\n",
					params.cmdname);
				exit(EXIT_FAILURE);
			}
			break;
		case 'p':
			params.pflag = strtoul(optarg, &ptr, 10);
			if (*ptr) {
				fprintf(stderr,
					"%s: invalid file position %s\n",
					params.cmdname, *argv);
				exit(EXIT_FAILURE);
			}
			break;
		case 'V':
			printf("dumpimage version %s\n", PLAIN_VERSION);
			exit(EXIT_SUCCESS);
		case 'h':
		default:
			usage();
			break;
		}
	}

	if (argc < 2 || (params.iflag && params.lflag))
		usage();

	if (optind >= argc) {
		fprintf(stderr, "%s: image file missing\n", params.cmdname);
		exit(EXIT_FAILURE);
	}

	params.imagefile = argv[optind];

	/* set tparams as per input type_id */
	tparams = imagetool_get_type(params.type);
	if (!params.lflag && tparams == NULL) {
		fprintf(stderr, "%s: unsupported type: %s\n",
			params.cmdname, genimg_get_type_name(params.type));
		exit(EXIT_FAILURE);
	}

	/*
	 * check the passed arguments parameters meets the requirements
	 * as per image type to be generated/listed
	 */
	if (tparams && tparams->check_params) {
		if (tparams->check_params(&params)) {
			fprintf(stderr, "%s: Parameter check failed\n",
				params.cmdname);
			exit(EXIT_FAILURE);
		}
	}

	if (!params.lflag && !params.outfile) {
		fprintf(stderr, "%s: No output file provided\n",
			params.cmdname);
		exit(EXIT_FAILURE);
	}

	ifd = open(params.imagefile, O_RDONLY|O_BINARY);
	if (ifd < 0) {
		fprintf(stderr, "%s: Can't open \"%s\": %s\n", params.cmdname,
			params.imagefile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (fstat(ifd, &sbuf) < 0) {
		fprintf(stderr, "%s: Can't stat \"%s\": %s\n", params.cmdname,
			params.imagefile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (tparams && (uint32_t)sbuf.st_size < tparams->header_size) {
		fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n",
			params.cmdname, params.imagefile);
		exit(EXIT_FAILURE);
	}

	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
	if (ptr == MAP_FAILED) {
		fprintf(stderr, "%s: Can't read \"%s\": %s\n", params.cmdname,
			params.imagefile, strerror(errno));
		exit(EXIT_FAILURE);
	}

	/*
	 * Both calls bellow scan through dumpimage registry for all
	 * supported image types and verify the input image file
	 * header for match
	 */
	if (params.iflag) {
		/*
		 * Extract the data files from within the matched
		 * image type. Returns the error code if not matched
		 */
		retval = dumpimage_extract_subimage(tparams, ptr, &sbuf);
		if (retval)
			fprintf(stderr, "%s: Can't extract subimage from %s\n",
				params.cmdname, params.imagefile);
	} else {
		/*
		 * Print the image information for matched image type
		 * Returns the error code if not matched
		 */
		retval = imagetool_verify_print_header(ptr, &sbuf, tparams,
						       &params);
	}

	(void)munmap((void *)ptr, sbuf.st_size);
	(void)close(ifd);

	return retval;
}

static void usage(void)
{
	fprintf(stderr, "Usage: %s [-T type] -l image\n"
		"          -l ==> list image header information\n"
		"          -T ==> parse image file as 'type'\n",
		params.cmdname);
	fprintf(stderr,
		"       %s [-T type] [-p position] [-o outfile] image\n"
		"          -T ==> declare image type as 'type'\n"
		"          -p ==> 'position' (starting at 0) of the component to extract from image\n"
		"          -o ==> extract component to file 'outfile'\n",
		params.cmdname);
	fprintf(stderr,
		"       %s -h ==> print usage information and exit\n",
		params.cmdname);
	fprintf(stderr,
		"       %s -V ==> print version information and exit\n",
		params.cmdname);

	exit(EXIT_SUCCESS);
}
