From 67aedf34fa041bab200e57e4f5bf88f65a1e2287 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 12 Jan 2007 09:00:48 +0000 Subject: [PATCH] Use systematic names for XXX_IMAGE. Add scripts as an image format (since it's trivial to do). --- src/config.h | 5 +- src/core/config.c | 13 ++++-- src/image/script.c | 113 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 src/image/script.c diff --git a/src/config.h b/src/config.h index d6e01134..b8ab9291 100644 --- a/src/config.h +++ b/src/config.h @@ -102,11 +102,12 @@ #undef ELF64_IMAGE /* ELF64 image support */ #undef ELF_IMAGE /* ELF image support */ #undef COFF_IMAGE /* COFF image support */ -#undef IMAGE_FREEBSD /* FreeBSD kernel image support */ -#undef IMAGE_MULTIBOOT /* MultiBoot image support */ +#undef FREEBSD_IMAGE /* FreeBSD kernel image support */ +#define MULTIBOOT_IMAGE /* MultiBoot image support */ #undef AOUT_IMAGE /* a.out image support */ #undef WINCE_IMAGE /* WinCE image support */ #undef PXE_IMAGE /* PXE image support */ +#define SCRIPT_IMAGE /* gPXE script image support */ /* @END general.h */ diff --git a/src/core/config.c b/src/core/config.c index 6120fc3b..7ec9a3bb 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -122,21 +122,24 @@ REQUIRE_OBJECT ( elf ); #ifdef COFF_IMAGE REQUIRE_OBJECT ( coff ); #endif -#ifdef IMAGE_FREEBSD +#ifdef FREEBSD_IMAGE REQUIRE_OBJECT ( freebsd ); #endif -#ifdef IMAGE_MULTIBOOT +#ifdef MULTIBOOT_IMAGE REQUIRE_OBJECT ( multiboot ); #endif -#ifdef AOUT_IMAGE +#ifdef AOUT_IMAGE REQUIRE_OBJECT ( aout ); #endif -#ifdef WINCE_IMAGE +#ifdef WINCE_IMAGE REQUIRE_OBJECT ( wince ); #endif -#ifdef PXE_IMAGE +#ifdef PXE_IMAGE REQUIRE_OBJECT ( pxe ); #endif +#ifdef SCRIPT_IMAGE +REQUIRE_OBJECT ( script ); +#endif /* * Drag in all requested commands diff --git a/src/image/script.c b/src/image/script.c new file mode 100644 index 00000000..0504e4d0 --- /dev/null +++ b/src/image/script.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2007 Michael Brown . + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/** + * @file + * + * gPXE scripts + * + */ + +#include +#include +#include +#include + +struct image_type script_image_type __image_type ( PROBE_NORMAL ); + +/** + * Execute script + * + * @v image Script + * @ret rc Return status code + */ +static int script_exec ( struct image *image ) { + char cmdbuf[256]; + size_t offset = 0; + size_t remaining; + size_t len; + char *eol; + int rc; + + while ( offset < image->len ) { + + /* Read up to cmdbuf bytes from script into buffer */ + remaining = ( image->len - offset ); + len = sizeof ( cmdbuf ); + if ( len > remaining ) + len = remaining; + copy_from_user ( cmdbuf, image->data, offset, len ); + + /* Find end of line */ + eol = memchr ( cmdbuf, '\n', sizeof ( cmdbuf ) ); + if ( ! eol ) + eol = memchr ( cmdbuf, '\0', sizeof ( cmdbuf ) ); + if ( ! eol ) { + DBG ( "Script line too long (max %d bytes)\n", + sizeof ( cmdbuf ) ); + return -ENOEXEC; + } + + /* Mark end of line and execute command */ + *eol = '\0'; + if ( ( rc = system ( cmdbuf ) ) != 0 ) { + DBG ( "Command \"%s\" exited with status %d\n", + cmdbuf, rc ); + return rc; + } + + /* Move to next line */ + offset += ( ( eol - cmdbuf ) + 1 ); + } + + return 0; +} + +/** + * Load script into memory + * + * @v image Script + * @ret rc Return status code + */ +static int script_load ( struct image *image ) { + static const char magic[] = "#!gpxe\n"; + char test[ sizeof ( magic ) - 1 ]; + + /* Check for magic signature */ + copy_from_user ( test, image->data, 0, sizeof ( test ) ); + if ( memcmp ( test, magic, sizeof ( test ) ) != 0 ) { + DBG ( "Invalid magic signature\n" ); + return -ENOEXEC; + } + + /* This is a script */ + image->type = &script_image_type; + + /* We don't actually load it anywhere; we will pick the lines + * out of the image as we need them. + */ + + return 0; +} + +/** Script image type */ +struct image_type script_image_type __image_type ( PROBE_NORMAL ) = { + .name = "script", + .load = script_load, + .exec = script_exec, +};