/*
 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <libgen.h>
#include <syslog.h>
#include <ipxe/list.h>
#include <ipxe/umalloc.h>
#include <ipxe/uri.h>
#include <ipxe/image.h>

/** @file
 *
 * Executable images
 *
 */

/* Disambiguate the various error causes */
#define EACCES_UNTRUSTED \
	__einfo_error ( EINFO_EACCES_UNTRUSTED )
#define EINFO_EACCES_UNTRUSTED \
	__einfo_uniqify ( EINFO_EACCES, 0x01, "Untrusted image" )
#define EACCES_PERMANENT \
	__einfo_error ( EINFO_EACCES_PERMANENT )
#define EINFO_EACCES_PERMANENT \
	__einfo_uniqify ( EINFO_EACCES, 0x02, "Trust requirement is permanent" )

/** List of registered images */
struct list_head images = LIST_HEAD_INIT ( images );

/** Image selected for execution */
struct image_tag selected_image __image_tag = {
	.name = "SELECTED",
};

/** Currently-executing image */
struct image_tag current_image __image_tag = {
	.name = "CURRENT",
};

/** Current image trust requirement */
static int require_trusted_images = 0;

/** Prevent changes to image trust requirement */
static int require_trusted_images_permanent = 0;

/**
 * Free executable image
 *
 * @v refcnt		Reference counter
 */
static void free_image ( struct refcnt *refcnt ) {
	struct image *image = container_of ( refcnt, struct image, refcnt );
	struct image_tag *tag;

	DBGC ( image, "IMAGE %s freed\n", image->name );
	for_each_table_entry ( tag, IMAGE_TAGS ) {
		if ( tag->image == image )
			tag->image = NULL;
	}
	free ( image->name );
	free ( image->cmdline );
	uri_put ( image->uri );
	ufree ( image->data );
	image_put ( image->replacement );
	free ( image );
}

/**
 * Allocate executable image
 *
 * @v uri		URI, or NULL
 * @ret image		Executable image
 */
struct image * alloc_image ( struct uri *uri ) {
	struct image *image;
	int rc;

	/* Allocate image */
	image = zalloc ( sizeof ( *image ) );
	if ( ! image )
		goto err_alloc;

	/* Initialise image */
	ref_init ( &image->refcnt, free_image );
	if ( uri && ( ( rc = image_set_uri ( image, uri ) ) != 0 ) )
		goto err_set_uri;

	return image;

 err_set_uri:
	image_put ( image );
 err_alloc:
	return NULL;
}

/**
 * Set image URI
 *
 * @v image		Image
 * @v uri		New image URI
 * @ret rc		Return status code
 */
int image_set_uri ( struct image *image, struct uri *uri ) {
	const char *name;
	int rc;

	/* Set name, if image does not already have one */
	if ( ! ( image->name && image->name[0] ) ) {
		name = ( uri->path ? uri->path : uri->opaque );
		if ( name ) {
			name = basename ( ( char * ) name );
			if ( ( rc = image_set_name ( image, name ) ) != 0 )
				return rc;
		}
	}

	/* Update image URI */
	uri_put ( image->uri );
	image->uri = uri_get ( uri );

	return 0;
}

/**
 * Set image name
 *
 * @v image		Image
 * @v name		New image name
 * @ret rc		Return status code
 */
int image_set_name ( struct image *image, const char *name ) {
	char *name_copy;

	/* Duplicate name */
	name_copy = strdup ( name );
	if ( ! name_copy )
		return -ENOMEM;

	/* Replace existing name */
	free ( image->name );
	image->name = name_copy;

	return 0;
}

/**
 * Set image command line
 *
 * @v image		Image
 * @v cmdline		New image command line, or NULL
 * @ret rc		Return status code
 */
int image_set_cmdline ( struct image *image, const char *cmdline ) {

	free ( image->cmdline );
	image->cmdline = NULL;
	if ( cmdline ) {
		image->cmdline = strdup ( cmdline );
		if ( ! image->cmdline )
			return -ENOMEM;
	}
	return 0;
}

/**
 * Set image length
 *
 * @v image		Image
 * @v len		Length of image data
 * @ret rc		Return status code
 */
int image_set_len ( struct image *image, size_t len ) {
	userptr_t new;

	/* (Re)allocate image data */
	new = urealloc ( image->data, len );
	if ( ! new )
		return -ENOMEM;
	image->data = new;
	image->len = len;

	return 0;
}

/**
 * Set image data
 *
 * @v image		Image
 * @v data		Image data
 * @v len		Length of image data
 * @ret rc		Return status code
 */
int image_set_data ( struct image *image, userptr_t data, size_t len ) {
	int rc;

	/* Set image length */
	if ( ( rc = image_set_len ( image, len ) ) != 0 )
		return rc;

	/* Copy in new image data */
	memcpy_user ( image->data, 0, data, 0, len );

	return 0;
}

/**
 * Determine image type
 *
 * @v image		Executable image
 * @ret rc		Return status code
 */
static int image_probe ( struct image *image ) {
	struct image_type *type;
	int rc;

	/* Try each type in turn */
	for_each_table_entry ( type, IMAGE_TYPES ) {
		if ( ( rc = type->probe ( image ) ) == 0 ) {
			image->type = type;
			DBGC ( image, "IMAGE %s is %s\n",
			       image->name, type->name );
			return 0;
		}
		DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
		       type->name, strerror ( rc ) );
	}

	DBGC ( image, "IMAGE %s format not recognised\n", image->name );
	return -ENOTSUP;
}

/**
 * Register executable image
 *
 * @v image		Executable image
 * @ret rc		Return status code
 */
int register_image ( struct image *image ) {
	static unsigned int imgindex = 0;
	char name[8]; /* "imgXXXX" */
	int rc;

	/* Create image name if it doesn't already have one */
	if ( ! image->name ) {
		snprintf ( name, sizeof ( name ), "img%d", imgindex++ );
		if ( ( rc = image_set_name ( image, name ) ) != 0 )
			return rc;
	}

	/* Add to image list */
	image_get ( image );
	image->flags |= IMAGE_REGISTERED;
	list_add_tail ( &image->list, &images );
	DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n",
	       image->name, user_to_phys ( image->data, 0 ),
	       user_to_phys ( image->data, image->len ) );

	/* Try to detect image type, if applicable.  Ignore failures,
	 * since we expect to handle some unrecognised images
	 * (e.g. kernel initrds, multiboot modules, random files
	 * provided via our EFI virtual filesystem, etc).
	 */
	if ( ! image->type )
		image_probe ( image );

	return 0;
}

/**
 * Unregister executable image
 *
 * @v image		Executable image
 */
void unregister_image ( struct image *image ) {

	/* Do nothing unless image is registered */
	if ( ! ( image->flags & IMAGE_REGISTERED ) )
		return;

	DBGC ( image, "IMAGE %s unregistered\n", image->name );
	list_del ( &image->list );
	image->flags &= ~IMAGE_REGISTERED;
	image_put ( image );
}

/**
 * Find image by name
 *
 * @v name		Image name
 * @ret image		Executable image, or NULL
 */
struct image * find_image ( const char *name ) {
	struct image *image;

	for_each_image ( image ) {
		if ( strcmp ( image->name, name ) == 0 )
			return image;
	}

	return NULL;
}

/**
 * Find image by tag
 *
 * @v tag		Image tag
 * @ret image		Executable image, or NULL
 */
struct image * find_image_tag ( struct image_tag *tag ) {
	struct image *image;

	for_each_image ( image ) {
		if ( tag->image == image )
			return image;
	}

	return NULL;
}

/**
 * Execute image
 *
 * @v image		Executable image
 * @ret rc		Return status code
 *
 * The image must already be registered.  Note that executing an image
 * may cause it to unregister itself.  The caller must therefore
 * assume that the image pointer becomes invalid.
 */
int image_exec ( struct image *image ) {
	struct image *saved_current_image;
	struct image *replacement = NULL;
	struct uri *old_cwuri;
	int rc;

	/* Sanity check */
	assert ( image->flags & IMAGE_REGISTERED );

	/* Switch current working directory to be that of the image
	 * itself, if applicable
	 */
	old_cwuri = uri_get ( cwuri );
	if ( image->uri )
		churi ( image->uri );

	/* Set as currently running image */
	saved_current_image = image_tag ( image, &current_image );

	/* Take out a temporary reference to the image, so that it
	 * does not get freed when temporarily unregistered.
	 */
	image_get ( image );

	/* Check that this image can be executed */
	if ( ! ( image->type && image->type->exec ) ) {
		rc = -ENOEXEC;
		goto err;
	}

	/* Check that image is trusted (if applicable) */
	if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
		DBGC ( image, "IMAGE %s is not trusted\n", image->name );
		rc = -EACCES_UNTRUSTED;
		goto err;
	}

	/* Record boot attempt */
	syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name );

	/* Temporarily unregister the image during its execution */
	unregister_image ( image );

	/* Try executing the image */
	if ( ( rc = image->type->exec ( image ) ) != 0 ) {
		DBGC ( image, "IMAGE %s could not execute: %s\n",
		       image->name, strerror ( rc ) );
		/* Do not return yet; we still have clean-up to do */
	}

	/* Record result of boot attempt */
	if ( rc == 0 ) {
		syslog ( LOG_NOTICE, "Execution of \"%s\" completed\n",
			 image->name );
	} else {
		syslog ( LOG_ERR, "Execution of \"%s\" failed: %s\n",
			 image->name, strerror ( rc ) );
	}

	/* Re-register image (unless due to be replaced) */
	if ( ! image->replacement )
		register_image ( image );

	/* Pick up replacement image before we drop the original
	 * image's temporary reference.  The replacement image must
	 * already be registered, so we don't need to hold a temporary
	 * reference (which would complicate the tail-recursion).
	 */
	replacement = image->replacement;
	if ( replacement )
		assert ( replacement->flags & IMAGE_REGISTERED );

 err:
	/* Unregister image if applicable */
	if ( image->flags & IMAGE_AUTO_UNREGISTER )
		unregister_image ( image );

	/* Debug message for tail-recursion.  Placed here because the
	 * image_put() may end up freeing the image.
	 */
	if ( replacement ) {
		DBGC ( image, "IMAGE %s replacing self with IMAGE %s\n",
		       image->name, replacement->name );
	}

	/* Drop temporary reference to the original image */
	image_put ( image );

	/* Restore previous currently-running image */
	image_tag ( saved_current_image, &current_image );

	/* Reset current working directory */
	churi ( old_cwuri );
	uri_put ( old_cwuri );

	/* Tail-recurse into replacement image, if one exists */
	if ( replacement )
		return image_exec ( replacement );

	return rc;
}

/**
 * Set replacement image
 *
 * @v replacement	Replacement image
 * @ret rc		Return status code
 *
 * The replacement image must already be registered, and must remain
 * registered until the currently-executing image returns.
 */
int image_replace ( struct image *replacement ) {
	struct image *image = current_image.image;
	int rc;

	/* Sanity check */
	assert ( replacement->flags & IMAGE_REGISTERED );

	/* Fail unless there is a currently-executing image */
	if ( ! image ) {
		rc = -ENOTTY;
		DBGC ( replacement, "IMAGE %s cannot replace non-existent "
		       "image: %s\n", replacement->name, strerror ( rc ) );
		return rc;
	}

	/* Check that the replacement image can be executed */
	if ( ! ( replacement->type && replacement->type->exec ) )
		return -ENOEXEC;

	/* Clear any existing replacement */
	image_put ( image->replacement );

	/* Set replacement */
	image->replacement = image_get ( replacement );
	DBGC ( image, "IMAGE %s will replace self with IMAGE %s\n",
	       image->name, replacement->name );

	return 0;
}

/**
 * Select image for execution
 *
 * @v image		Executable image
 * @ret rc		Return status code
 */
int image_select ( struct image *image ) {

	/* Check that this image can be executed */
	if ( ! ( image->type && image->type->exec ) )
		return -ENOEXEC;

	/* Mark image as selected */
	image_tag ( image, &selected_image );

	return 0;
}

/**
 * Change image trust requirement
 *
 * @v require_trusted	Require trusted images
 * @v permanent		Make trust requirement permanent
 * @ret rc		Return status code
 */
int image_set_trust ( int require_trusted, int permanent ) {

	/* Update trust requirement, if permitted to do so */
	if ( ! require_trusted_images_permanent ) {
		require_trusted_images = require_trusted;
		require_trusted_images_permanent = permanent;
	}

	/* Fail if we attempted to change the trust requirement but
	 * were not permitted to do so.
	 */
	if ( require_trusted_images != require_trusted )
		return -EACCES_PERMANENT;

	return 0;
}

/**
 * Create registered image from block of memory
 *
 * @v name		Name
 * @v data		Image data
 * @v len		Length
 * @ret image		Image, or NULL on error
 */
struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
	struct image *image;
	int rc;

	/* Allocate image */
	image = alloc_image ( NULL );
	if ( ! image ) {
		rc = -ENOMEM;
		goto err_alloc_image;
	}

	/* Set name */
	if ( ( rc = image_set_name ( image, name ) ) != 0 )
		goto err_set_name;

	/* Set data */
	if ( ( rc = image_set_data ( image, data, len ) ) != 0 )
		goto err_set_data;

	/* Register image */
	if ( ( rc = register_image ( image ) ) != 0 )
		goto err_register;

	/* Drop local reference to image */
	image_put ( image );

	return image;

 err_register:
 err_set_data:
 err_set_name:
	image_put ( image );
 err_alloc_image:
	return NULL;
}

/**
 * Find argument within image command line
 *
 * @v image		Image
 * @v key		Argument search key (including trailing delimiter)
 * @ret value		Argument value, or NULL if not found
 */
const char * image_argument ( struct image *image, const char *key ) {
	const char *cmdline = image->cmdline;
	const char *search;
	const char *match;
	const char *next;

	/* Find argument */
	for ( search = cmdline ; search ; search = next ) {

		/* Find next occurrence, if any */
		match = strstr ( search, key );
		if ( ! match )
			break;
		next = ( match + strlen ( key ) );

		/* Check preceding delimiter, if any */
		if ( ( match == cmdline ) || isspace ( match[-1] ) )
			return next;
	}

	return NULL;
}
