/* Copyright 2020 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* For strdup */
#define _POSIX_C_SOURCE 200809L

#include <fcntl.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "2api.h"
#include "2return_codes.h"
#include "host_misc.h"
#include "flashrom.h"
#include "subprocess.h"

#define FLASHROM_EXEC_NAME "flashrom"

/**
 * Helper to create a temporary file, and optionally write some data
 * into it.
 *
 * @param data		If data needs to be written to the file, a
 *			pointer to the buffer.  Pass NULL to just
 *			create an empty temporary file.
 * @param data_size	The size of the buffer to write, if applicable.
 * @param path_out	An output pointer for the filename.  Caller
 *			should free.
 *
 * @return VB2_SUCCESS on success, or a relevant error.
 */
static vb2_error_t write_temp_file(const uint8_t *data, uint32_t data_size,
				   char **path_out)
{
	int fd;
	ssize_t write_rv;
	vb2_error_t rv;
	char *path;

	*path_out = NULL;
	path = strdup(P_tmpdir "/vb2_flashrom.XXXXXX");

	fd = mkstemp(path);
	if (fd < 0) {
		rv = VB2_ERROR_WRITE_FILE_OPEN;
		goto fail;
	}

	while (data && data_size > 0) {
		write_rv = write(fd, data, data_size);
		if (write_rv < 0) {
			close(fd);
			unlink(path);
			rv = VB2_ERROR_WRITE_FILE_DATA;
			goto fail;
		}

		data_size -= write_rv;
		data += write_rv;
	}

	close(fd);
	*path_out = path;
	return VB2_SUCCESS;

 fail:
	free(path);
	return rv;
}

static vb2_error_t run_flashrom(const char *const argv[])
{
	int status = subprocess_run(argv, &subprocess_null, &subprocess_null,
				    &subprocess_null);
	if (status) {
		fprintf(stderr, "Flashrom invocation failed (exit status %d):",
			status);

		for (const char *const *argp = argv; *argp; argp++)
			fprintf(stderr, " %s", *argp);

		fprintf(stderr, "\n");
		return VB2_ERROR_FLASHROM;
	}

	return VB2_SUCCESS;
}

vb2_error_t flashrom_read(const char *programmer, const char *region,
			  uint8_t **data_out, uint32_t *size_out)
{
	char *tmpfile;
	char region_param[PATH_MAX];
	vb2_error_t rv;

	*data_out = NULL;
	*size_out = 0;

	VB2_TRY(write_temp_file(NULL, 0, &tmpfile));

	if (region)
		snprintf(region_param, sizeof(region_param), "%s:%s", region,
			 tmpfile);

	const char *const argv[] = {
		FLASHROM_EXEC_NAME,
		"-p",
		programmer,
		"-r",
		region ? "-i" : tmpfile,
		region ? region_param : NULL,
		NULL,
	};

	rv = run_flashrom(argv);
	if (rv == VB2_SUCCESS)
		rv = vb2_read_file(tmpfile, data_out, size_out);

	unlink(tmpfile);
	free(tmpfile);
	return rv;
}

vb2_error_t flashrom_write(const char *programmer, const char *region,
			   uint8_t *data, uint32_t size)
{
	char *tmpfile;
	char region_param[PATH_MAX];
	vb2_error_t rv;

	VB2_TRY(write_temp_file(data, size, &tmpfile));

	if (region)
		snprintf(region_param, sizeof(region_param), "%s:%s", region,
			 tmpfile);

	const char *const argv[] = {
		FLASHROM_EXEC_NAME,
		"-p",
		programmer,
		"--fast-verify",
		"-w",
		region ? "-i" : tmpfile,
		region ? region_param : NULL,
		NULL,
	};

	rv = run_flashrom(argv);
	unlink(tmpfile);
	free(tmpfile);
	return rv;
}
