diff options
Diffstat (limited to 'contrib/syslinux-4.02/gpxe/src/hci')
37 files changed, 4583 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/autoboot_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/autoboot_cmd.c new file mode 100644 index 0000000..95b172d --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/autoboot_cmd.c @@ -0,0 +1,27 @@ +#include <stdio.h> +#include <gpxe/command.h> +#include <usr/autoboot.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static int autoboot_exec ( int argc, char **argv ) { + + if ( argc != 1 ) { + printf ( "Usage:\n" + " %s\n" + "\n" + "Attempts to boot the system\n", + argv[0] ); + return 1; + } + + autoboot(); + + /* Can never return success by definition */ + return 1; +} + +struct command autoboot_command __command = { + .name = "autoboot", + .exec = autoboot_exec, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/config_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/config_cmd.c new file mode 100644 index 0000000..a9e1f16 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/config_cmd.c @@ -0,0 +1,39 @@ +#include <string.h> +#include <stdio.h> +#include <gpxe/command.h> +#include <gpxe/settings.h> +#include <gpxe/settings_ui.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static int config_exec ( int argc, char **argv ) { + char *settings_name; + struct settings *settings; + int rc; + + if ( argc > 2 ) { + printf ( "Usage: %s [scope]\n" + "Opens the option configuration console\n", argv[0] ); + return 1; + } + + settings_name = ( ( argc == 2 ) ? argv[1] : "" ); + settings = find_settings ( settings_name ); + if ( ! settings ) { + printf ( "No such scope \"%s\"\n", settings_name ); + return 1; + } + + if ( ( rc = settings_ui ( settings ) ) != 0 ) { + printf ( "Could not save settings: %s\n", + strerror ( rc ) ); + return 1; + } + + return 0; +} + +struct command config_command __command = { + .name = "config", + .exec = config_exec, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/dhcp_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/dhcp_cmd.c new file mode 100644 index 0000000..96aac8d --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/dhcp_cmd.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2007 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <stddef.h> +#include <string.h> +#include <assert.h> +#include <getopt.h> +#include <gpxe/netdevice.h> +#include <gpxe/in.h> +#include <gpxe/command.h> +#include <usr/dhcpmgmt.h> + +/** @file + * + * DHCP management commands + * + */ + +/** + * "dhcp" command syntax message + * + * @v argv Argument list + */ +static void dhcp_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <interface>\n" + "\n" + "Configure a network interface using DHCP\n", + argv[0] ); +} + +/** + * The "dhcp" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int dhcp_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + const char *netdev_txt; + struct net_device *netdev; + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + dhcp_syntax ( argv ); + return 1; + } + } + + /* Need exactly one interface name remaining after the options */ + if ( optind != ( argc - 1 ) ) { + dhcp_syntax ( argv ); + return 1; + } + netdev_txt = argv[optind]; + + /* Parse arguments */ + netdev = find_netdev ( netdev_txt ); + if ( ! netdev ) { + printf ( "No such interface: %s\n", netdev_txt ); + return 1; + } + + /* Perform DHCP */ + if ( ( rc = dhcp ( netdev ) ) != 0 ) { + printf ( "Could not configure %s: %s\n", netdev->name, + strerror ( rc ) ); + return 1; + } + + return 0; +} + +/** + * "pxebs" command syntax message + * + * @v argv Argument list + */ +static void pxebs_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <interface> <server_type>\n" + "\n" + "Perform PXE Boot Server discovery\n", + argv[0] ); +} + +/** + * The "pxebs" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int pxebs_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + const char *netdev_txt; + const char *pxe_type_txt; + struct net_device *netdev; + unsigned int pxe_type; + char *end; + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + pxebs_syntax ( argv ); + return 1; + } + } + if ( optind != ( argc - 2 ) ) { + pxebs_syntax ( argv ); + return 1; + } + netdev_txt = argv[optind]; + pxe_type_txt = argv[ optind + 1 ]; + + /* Parse arguments */ + netdev = find_netdev ( netdev_txt ); + if ( ! netdev ) { + printf ( "No such interface: %s\n", netdev_txt ); + return 1; + } + pxe_type = strtoul ( pxe_type_txt, &end, 0 ); + if ( *end ) { + printf ( "Bad server type: %s\n", pxe_type_txt ); + return 1; + } + + /* Perform Boot Server Discovery */ + if ( ( rc = pxebs ( netdev, pxe_type ) ) != 0 ) { + printf ( "Could not discover boot server on %s: %s\n", + netdev->name, strerror ( rc ) ); + return 1; + } + + return 0; +} + +/** DHCP management commands */ +struct command dhcp_commands[] __command = { + { + .name = "dhcp", + .exec = dhcp_exec, + }, + { + .name = "pxebs", + .exec = pxebs_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/digest_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/digest_cmd.c new file mode 100644 index 0000000..bc6e551 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/digest_cmd.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2009 Daniel Verkamp <daniel@drv.nu>. + * + * 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. + */ + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <gpxe/command.h> +#include <gpxe/image.h> +#include <gpxe/crypto.h> + +#include <gpxe/md5.h> +#include <gpxe/sha1.h> + +/** + * "digest" command syntax message + * + * @v argv Argument list + */ +static void digest_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <image name>\n" + "\n" + "Calculate the %s of an image\n", + argv[0], argv[0] ); +} + +/** + * The "digest" command + * + * @v argc Argument count + * @v argv Argument list + * @v digest Digest algorithm + * @ret rc Exit code + */ +static int digest_exec ( int argc, char **argv, + struct digest_algorithm *digest ) { + const char *image_name; + struct image *image; + uint8_t digest_ctx[digest->ctxsize]; + uint8_t digest_out[digest->digestsize]; + uint8_t buf[128]; + size_t offset; + size_t len; + size_t frag_len; + int i; + unsigned j; + + if ( argc < 2 || + !strcmp ( argv[1], "--help" ) || + !strcmp ( argv[1], "-h" ) ) { + digest_syntax ( argv ); + return 1; + } + + for ( i = 1 ; i < argc ; i++ ) { + image_name = argv[i]; + + /* find image */ + image = find_image ( image_name ); + if ( ! image ) { + printf ( "No such image: %s\n", image_name ); + continue; + } + offset = 0; + len = image->len; + + /* calculate digest */ + digest_init ( digest, digest_ctx ); + while ( len ) { + frag_len = len; + if ( frag_len > sizeof ( buf ) ) + frag_len = sizeof ( buf ); + copy_from_user ( buf, image->data, offset, frag_len ); + digest_update ( digest, digest_ctx, buf, frag_len ); + len -= frag_len; + offset += frag_len; + } + digest_final ( digest, digest_ctx, digest_out ); + + for ( j = 0 ; j < sizeof ( digest_out ) ; j++ ) + printf ( "%02x", digest_out[j] ); + + printf ( " %s\n", image->name ); + } + + return 0; +} + +static int md5sum_exec ( int argc, char **argv ) { + return digest_exec ( argc, argv, &md5_algorithm ); +} + +static int sha1sum_exec ( int argc, char **argv ) { + return digest_exec ( argc, argv, &sha1_algorithm ); +} + +struct command md5sum_command __command = { + .name = "md5sum", + .exec = md5sum_exec, +}; + +struct command sha1sum_command __command = { + .name = "sha1sum", + .exec = sha1sum_exec, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/gdbstub_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/gdbstub_cmd.c new file mode 100644 index 0000000..7416752 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/gdbstub_cmd.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2008 Stefan Hajnoczi <stefanha@gmail.com>. + * + * 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. + */ + +#include <stdio.h> +#include <getopt.h> +#include <gpxe/command.h> +#include <gpxe/gdbstub.h> + +/** @file + * + * GDB stub command + * + */ + +/** + * "gdbstub" command syntax message + * + * @v argv Argument list + */ +static void gdbstub_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <transport> [<options>...]\n" + "\n" + "Start remote debugging using one of the following transports:\n" + " serial use serial port (if compiled in)\n" + " udp <interface> use UDP over network interface (if compiled in)\n", + argv[0] ); +} + +/** + * The "gdbstub" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int gdbstub_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + const char *trans_name; + struct gdb_transport *trans; + int c; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + gdbstub_syntax ( argv ); + return 1; + } + } + + /* At least one argument */ + if ( optind == argc ) { + gdbstub_syntax ( argv ); + return 1; + } + + trans_name = argv[optind++]; + + /* Initialise transport */ + trans = find_gdb_transport ( trans_name ); + if ( !trans ) { + printf ( "%s: no such transport (is it compiled in?)\n", trans_name ); + return 1; + } + + if ( trans->init ) { + if ( trans->init ( argc - optind, &argv[optind] ) != 0 ) { + return 1; + } + } + + /* Enter GDB stub */ + gdbstub_start ( trans ); + return 0; +} + +/** GDB stub commands */ +struct command gdbstub_commands[] __command = { + { + .name = "gdbstub", + .exec = gdbstub_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/ifmgmt_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/ifmgmt_cmd.c new file mode 100644 index 0000000..ad069f1 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/ifmgmt_cmd.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2007 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdio.h> +#include <getopt.h> +#include <gpxe/netdevice.h> +#include <gpxe/command.h> +#include <usr/ifmgmt.h> +#include <hci/ifmgmt_cmd.h> + +/** @file + * + * Network interface management commands + * + */ + +/** Options shared by all if<xxx> commands */ +static struct option ifcommon_longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, +}; + +/** + * Print syntax of if<xxx> command + * + * @v argv Command arguments + * @v verb Verb describing the action of the command + */ +static void ifcommon_syntax ( char **argv, const char *verb ) { + printf ( "Usage:\n" + " %s [<interface>] [<interface>...]\n" + "\n" + "%s the specified network interfaces\n", + argv[0], verb ); +} + +/** + * Execute if<xxx> command over all network devices + * + * @v payload Command to execute + * @ret rc Exit code + */ +static int ifcommon_do_all ( int ( * payload ) ( struct net_device * ) ) { + struct net_device *netdev; + int rc = 0; + + /* Execute payload for each network device */ + for_each_netdev ( netdev ) { + if ( payload ( netdev ) != 0 ) + rc = 1; + } + return rc; +} + +/** + * Execute if<xxx> command over list of network devices + * + * @v payload Command to execute + * @ret rc Exit code + */ +static int ifcommon_do_list ( int ( * payload ) ( struct net_device * ), + char **list, unsigned int count ) { + const char *netdev_name; + struct net_device *netdev; + int rc = 0; + + while ( count-- ) { + netdev_name = *(list++); + netdev = find_netdev ( netdev_name ); + if ( ! netdev ) { + printf ( "%s: no such interface\n", netdev_name ); + rc = 1; + continue; + } + if ( payload ( netdev ) != 0 ) + rc = 1; + } + return rc; +} + +/** + * Execute if<xxx> command + * + * @v argc Argument count + * @v argv Argument list + * @v payload Command to execute + * @v verb Verb describing the action of the command + * @ret rc Exit code + */ +int ifcommon_exec ( int argc, char **argv, + int ( * payload ) ( struct net_device * ), + const char *verb ) { + int c; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", ifcommon_longopts, + NULL ) ) >= 0 ) { + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + ifcommon_syntax ( argv, verb ); + return 1; + } + } + + if ( optind == argc ) { + return ifcommon_do_all ( payload ); + } else { + return ifcommon_do_list ( payload, &argv[optind], + ( argc - optind ) ); + } +} + +/* "ifopen" command */ + +static int ifopen_payload ( struct net_device *netdev ) { + return ifopen ( netdev ); +} + +static int ifopen_exec ( int argc, char **argv ) { + return ifcommon_exec ( argc, argv, ifopen_payload, "Open" ); +} + +/* "ifclose" command */ + +static int ifclose_payload ( struct net_device *netdev ) { + ifclose ( netdev ); + return 0; +} + +static int ifclose_exec ( int argc, char **argv ) { + return ifcommon_exec ( argc, argv, ifclose_payload, "Close" ); +} + +/* "ifstat" command */ + +static int ifstat_payload ( struct net_device *netdev ) { + ifstat ( netdev ); + return 0; +} + +static int ifstat_exec ( int argc, char **argv ) { + return ifcommon_exec ( argc, argv, + ifstat_payload, "Display status of" ); +} + +/** Interface management commands */ +struct command ifmgmt_commands[] __command = { + { + .name = "ifopen", + .exec = ifopen_exec, + }, + { + .name = "ifclose", + .exec = ifclose_exec, + }, + { + .name = "ifstat", + .exec = ifstat_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/image_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/image_cmd.c new file mode 100644 index 0000000..33994b5 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/image_cmd.c @@ -0,0 +1,608 @@ +/* + * Copyright (C) 2007 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <libgen.h> +#include <getopt.h> +#include <gpxe/image.h> +#include <gpxe/command.h> +#include <usr/imgmgmt.h> + +/** @file + * + * Image management commands + * + */ + +enum image_action { + IMG_FETCH = 0, + IMG_LOAD, + IMG_EXEC, +}; + +/** + * Fill in image command line + * + * @v image Image + * @v nargs Argument count + * @v args Argument list + * @ret rc Return status code + */ +static int imgfill_cmdline ( struct image *image, unsigned int nargs, + char **args ) { + size_t len; + unsigned int i; + + /* Determine total length of command line */ + len = 1; /* NUL */ + for ( i = 0 ; i < nargs ; i++ ) + len += ( 1 /* possible space */ + strlen ( args[i] ) ); + + { + char buf[len]; + char *ptr = buf; + + /* Assemble command line */ + buf[0] = '\0'; + for ( i = 0 ; i < nargs ; i++ ) { + ptr += sprintf ( ptr, "%s%s", ( i ? " " : "" ), + args[i] ); + } + assert ( ptr < ( buf + len ) ); + + return image_set_cmdline ( image, buf ); + } +} + +/** + * "imgfetch"/"module"/"kernel" command syntax message + * + * @v argv Argument list + */ +static void imgfetch_core_syntax ( char **argv, enum image_action action ) { + static const char *actions[] = { + [IMG_FETCH] = "Fetch", + [IMG_LOAD] = "Fetch and load", + [IMG_EXEC] = "Fetch and execute", + }; + + printf ( "Usage:\n" + " %s [-n|--name <name>] filename [arguments...]\n" + "\n" + "%s executable/loadable image\n", + argv[0], actions[action] ); +} + +/** + * The "imgfetch"/"module"/"kernel" command body + * + * @v image_type Image type to assign (or NULL) + * @v load Image will be automatically loaded after fetching + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgfetch_core_exec ( struct image_type *image_type, + enum image_action action, + int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { "name", required_argument, NULL, 'n' }, + { NULL, 0, NULL, 0 }, + }; + struct image *image; + const char *name = NULL; + char *filename; + int ( * image_register ) ( struct image *image ); + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "hn:", + longopts, NULL ) ) >= 0 ) { + switch ( c ) { + case 'n': + /* Set image name */ + name = optarg; + break; + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + imgfetch_core_syntax ( argv, action ); + return -EINVAL; + } + } + + /* Need at least a filename remaining after the options */ + if ( optind == argc ) { + imgfetch_core_syntax ( argv, action ); + return -EINVAL; + } + filename = argv[optind++]; + if ( ! name ) + name = basename ( filename ); + + /* Allocate image */ + image = alloc_image(); + if ( ! image ) { + printf ( "%s\n", strerror ( -ENOMEM ) ); + return -ENOMEM; + } + + /* Fill in image name */ + if ( name ) { + if ( ( rc = image_set_name ( image, name ) ) != 0 ) + return rc; + } + + /* Set image type (if specified) */ + image->type = image_type; + + /* Fill in command line */ + if ( ( rc = imgfill_cmdline ( image, ( argc - optind ), + &argv[optind] ) ) != 0 ) + return rc; + + /* Fetch the image */ + switch ( action ) { + case IMG_FETCH: + image_register = register_image; + break; + case IMG_LOAD: + image_register = register_and_autoload_image; + break; + case IMG_EXEC: + image_register = register_and_autoexec_image; + break; + default: + assert ( 0 ); + return -EINVAL; + } + if ( ( rc = imgfetch ( image, filename, image_register ) ) != 0 ) { + printf ( "Could not fetch %s: %s\n", + filename, strerror ( rc ) ); + image_put ( image ); + return rc; + } + + image_put ( image ); + return 0; +} + +/** + * The "imgfetch"/"module" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int imgfetch_exec ( int argc, char **argv ) { + int rc; + + if ( ( rc = imgfetch_core_exec ( NULL, IMG_FETCH, + argc, argv ) ) != 0 ) + return rc; + + return 0; +} + +/** + * The "kernel" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int kernel_exec ( int argc, char **argv ) { + int rc; + + if ( ( rc = imgfetch_core_exec ( NULL, IMG_LOAD, argc, argv ) ) != 0 ) + return rc; + + return 0; +} + +/** + * The "chain" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int chain_exec ( int argc, char **argv) { + int rc; + + if ( ( rc = imgfetch_core_exec ( NULL, IMG_EXEC, argc, argv ) ) != 0 ) + return rc; + + return 0; +} + +/** + * "imgload" command syntax message + * + * @v argv Argument list + */ +static void imgload_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <image name>\n" + "\n" + "Load executable/loadable image\n", + argv[0] ); +} + +/** + * The "imgload" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int imgload_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + struct image *image; + const char *name; + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + imgload_syntax ( argv ); + return 1; + } + } + + /* Need exactly one image name remaining after the options */ + if ( optind != ( argc - 1 ) ) { + imgload_syntax ( argv ); + return 1; + } + name = argv[optind]; + + /* Load all specified images */ + image = find_image ( name ); + if ( ! image ) { + printf ( "No such image: %s\n", name ); + return 1; + } + if ( ( rc = imgload ( image ) ) != 0 ) { + printf ( "Could not load %s: %s\n", name, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * "imgargs" command syntax message + * + * @v argv Argument list + */ +static void imgargs_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <image name> [<arguments>...]\n" + "\n" + "Set arguments for executable/loadable image\n", + argv[0] ); +} + +/** + * The "imgargs" command body + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int imgargs_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + struct image *image; + const char *name; + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + imgargs_syntax ( argv ); + return 1; + } + } + + /* Need at least an image name remaining after the options */ + if ( optind == argc ) { + imgargs_syntax ( argv ); + return 1; + } + name = argv[optind++]; + + /* Fill in command line */ + image = find_image ( name ); + if ( ! image ) { + printf ( "No such image: %s\n", name ); + return 1; + } + if ( ( rc = imgfill_cmdline ( image, ( argc - optind ), + &argv[optind] ) ) != 0 ) + return rc; + + + return 0; +} + +/** + * "imgexec" command syntax message + * + * @v argv Argument list + */ +static void imgexec_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <image name>\n" + "\n" + "Execute executable/loadable image\n", + argv[0] ); +} + +/** + * The "imgexec" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int imgexec_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + struct image *image; + const char *name = NULL; + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + imgexec_syntax ( argv ); + return 1; + } + } + + /* Need no more than one image name */ + if ( optind != argc ) + name = argv[optind++]; + if ( optind != argc ) { + imgexec_syntax ( argv ); + return 1; + } + + /* Execute specified image */ + if ( name ) { + image = find_image ( name ); + if ( ! image ) { + printf ( "No such image: %s\n", name ); + return 1; + } + } else { + image = imgautoselect(); + if ( ! image ) { + printf ( "No (unique) loaded image\n" ); + return 1; + } + } + + if ( ( rc = imgexec ( image ) ) != 0 ) { + printf ( "Could not execute %s: %s\n", + image->name, strerror ( rc ) ); + return 1; + } + + return 0; +} + +/** + * "imgstat" command syntax message + * + * @v argv Argument list + */ +static void imgstat_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s\n" + "\n" + "List executable/loadable images\n", + argv[0] ); +} + +/** + * The "imgstat" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int imgstat_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + struct image *image; + int c; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + imgstat_syntax ( argv ); + return 1; + } + } + + /* No arguments */ + if ( optind != argc ) { + imgstat_syntax ( argv ); + return 1; + } + + /* Show status of all images */ + for_each_image ( image ) { + imgstat ( image ); + } + return 0; +} + +/** + * "imgstat" command syntax message + * + * @v argv Argument list + */ +static void imgfree_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s [<image name>]\n" + "\n" + "Free one or all executable/loadable images\n", + argv[0] ); +} + +/** + * The "imgfree" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int imgfree_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + struct image *image; + struct image *tmp; + const char *name = NULL; + int c; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + imgfree_syntax ( argv ); + return 1; + } + } + + /* Need no more than one image name */ + if ( optind != argc ) + name = argv[optind++]; + if ( optind != argc ) { + imgfree_syntax ( argv ); + return 1; + } + + if ( name ) { + /* Free specified image (may leak) */ + image = find_image ( name ); + if ( ! image ) { + printf ( "No such image: %s\n", name ); + return 1; + } + imgfree ( image ); + } else { + /* Free all images */ + list_for_each_entry_safe ( image, tmp, &images, list ) { + imgfree ( image ); + } + } + return 0; +} + +/** Image management commands */ +struct command image_commands[] __command = { + { + .name = "imgfetch", + .exec = imgfetch_exec, + }, + { + .name = "module", + .exec = imgfetch_exec, /* synonym for "imgfetch" */ + }, + { + .name = "initrd", + .exec = imgfetch_exec, /* synonym for "imgfetch" */ + }, + { + .name = "kernel", + .exec = kernel_exec, + }, + { + .name = "chain", + .exec = chain_exec, + }, + { + .name = "imgload", + .exec = imgload_exec, + }, + { + .name = "imgargs", + .exec = imgargs_exec, + }, + { + .name = "imgexec", + .exec = imgexec_exec, + }, + { + .name = "boot", /* synonym for "imgexec" */ + .exec = imgexec_exec, + }, + { + .name = "imgstat", + .exec = imgstat_exec, + }, + { + .name = "imgfree", + .exec = imgfree_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/iwmgmt_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/iwmgmt_cmd.c new file mode 100644 index 0000000..006c9f1 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/iwmgmt_cmd.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * 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_LICENCE ( GPL2_OR_LATER ); + +#include <gpxe/netdevice.h> +#include <gpxe/net80211.h> +#include <gpxe/command.h> +#include <usr/iwmgmt.h> +#include <hci/ifmgmt_cmd.h> + +/* "iwstat" command */ + +static int iwstat_payload ( struct net_device *netdev ) { + struct net80211_device *dev = net80211_get ( netdev ); + + if ( dev ) + iwstat ( dev ); + + return 0; +} + +static int iwstat_exec ( int argc, char **argv ) { + return ifcommon_exec ( argc, argv, + iwstat_payload, "Display wireless status of" ); +} + +/* "iwlist" command */ + +static int iwlist_payload ( struct net_device *netdev ) { + struct net80211_device *dev = net80211_get ( netdev ); + + if ( dev ) + return iwlist ( dev ); + + return 0; +} + +static int iwlist_exec ( int argc, char **argv ) { + return ifcommon_exec ( argc, argv, iwlist_payload, + "List wireless networks available via" ); +} + +/** Wireless interface management commands */ +struct command iwmgmt_commands[] __command = { + { + .name = "iwstat", + .exec = iwstat_exec, + }, + { + .name = "iwlist", + .exec = iwlist_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/login_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/login_cmd.c new file mode 100644 index 0000000..0da2497 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/login_cmd.c @@ -0,0 +1,29 @@ +#include <string.h> +#include <stdio.h> +#include <gpxe/command.h> +#include <gpxe/login_ui.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static int login_exec ( int argc, char **argv ) { + int rc; + + if ( argc > 1 ) { + printf ( "Usage: %s\n" + "Prompt for login credentials\n", argv[0] ); + return 1; + } + + if ( ( rc = login_ui() ) != 0 ) { + printf ( "Could not set credentials: %s\n", + strerror ( rc ) ); + return 1; + } + + return 0; +} + +struct command login_command __command = { + .name = "login", + .exec = login_exec, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/nvo_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/nvo_cmd.c new file mode 100644 index 0000000..5eb2f06 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/nvo_cmd.c @@ -0,0 +1,79 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <getopt.h> +#include <gpxe/settings.h> +#include <gpxe/command.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static int show_exec ( int argc, char **argv ) { + char buf[256]; + int rc; + + if ( argc != 2 ) { + printf ( "Syntax: %s <identifier>\n", argv[0] ); + return 1; + } + + if ( ( rc = fetchf_named_setting ( argv[1], buf, + sizeof ( buf ) ) ) < 0 ){ + printf ( "Could not find \"%s\": %s\n", + argv[1], strerror ( rc ) ); + return 1; + } + + printf ( "%s = %s\n", argv[1], buf ); + return 0; +} + +static int set_exec ( int argc, char **argv ) { + int rc; + + if ( argc != 3 ) { + printf ( "Syntax: %s <identifier> <value>\n", argv[0] ); + return 1; + } + + if ( ( rc = storef_named_setting ( argv[1], argv[2] ) ) != 0 ) { + printf ( "Could not set \"%s\"=\"%s\": %s\n", + argv[1], argv[2], strerror ( rc ) ); + return 1; + } + + return 0; +} + +static int clear_exec ( int argc, char **argv ) { + int rc; + + if ( argc != 2 ) { + printf ( "Syntax: %s <identifier>\n", argv[0] ); + return 1; + } + + if ( ( rc = delete_named_setting ( argv[1] ) ) != 0 ) { + printf ( "Could not clear \"%s\": %s\n", + argv[1], strerror ( rc ) ); + return 1; + } + + return 0; +} + +struct command nvo_commands[] __command = { + { + .name = "show", + .exec = show_exec, + }, + { + .name = "set", + .exec = set_exec, + }, + { + .name = "clear", + .exec = clear_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/route_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/route_cmd.c new file mode 100644 index 0000000..4372e34 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/route_cmd.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdio.h> +#include <getopt.h> +#include <gpxe/command.h> +#include <usr/route.h> + +/** @file + * + * Routing table management commands + * + */ + +/** + * "route" command syntax message + * + * @v argv Argument list + */ +static void route_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s\n" + "\n" + "Displays the routing table\n", + argv[0] ); +} + +/** + * The "route" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int route_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + + int c; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + route_syntax ( argv ); + return 1; + } + } + + if ( optind != argc ) { + route_syntax ( argv ); + return 1; + } + + route(); + return 0; +} + +/** Routing table management commands */ +struct command route_commands[] __command = { + { + .name = "route", + .exec = route_exec, + }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/sanboot_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/sanboot_cmd.c new file mode 100644 index 0000000..783b747 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/sanboot_cmd.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <string.h> +#include <getopt.h> +#include <gpxe/command.h> +#include <usr/autoboot.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * "sanboot" command syntax message + * + * @v argv Argument list + */ +static void sanboot_syntax ( char **argv ) { + printf ( "Usage:\n" + " %s <root-path>\n" + "\n" + "Boot from SAN target\n", + argv[0] ); +} + +/** + * The "sanboot" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Exit code + */ +static int sanboot_exec ( int argc, char **argv ) { + static struct option longopts[] = { + { "help", 0, NULL, 'h' }, + { NULL, 0, NULL, 0 }, + }; + const char *root_path = NULL; + int c; + int rc; + + /* Parse options */ + while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){ + switch ( c ) { + case 'h': + /* Display help text */ + default: + /* Unrecognised/invalid option */ + sanboot_syntax ( argv ); + return 1; + } + } + + /* Need exactly one image name remaining after the options */ + if ( optind != ( argc - 1 ) ) { + sanboot_syntax ( argv ); + return 1; + } + root_path = argv[optind]; + + /* Boot from root path */ + if ( ( rc = boot_root_path ( root_path ) ) != 0 ) { + printf ( "Could not boot from %s: %s\n", + root_path, strerror ( rc ) ); + return 1; + } + + return 0; +} + +struct command sanboot_command __command = { + .name = "sanboot", + .exec = sanboot_exec, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/commands/time_cmd.c b/contrib/syslinux-4.02/gpxe/src/hci/commands/time_cmd.c new file mode 100644 index 0000000..947410e --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/commands/time_cmd.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2009 Daniel Verkamp <daniel@drv.nu>. + * + * 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. + * + * March-19-2009 @ 02:44: Added sleep command. + * Shao Miller <shao.miller@yrdsb.edu.on.ca>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <gpxe/command.h> +#include <gpxe/nap.h> +#include <gpxe/timer.h> + +static int time_exec ( int argc, char **argv ) { + unsigned long start; + int rc, secs; + + if ( argc == 1 || + !strcmp ( argv[1], "--help" ) || + !strcmp ( argv[1], "-h" ) ) + { + printf ( "Usage:\n" + " %s <command>\n" + "\n" + "Time a command\n", + argv[0] ); + return 1; + } + + start = currticks(); + rc = execv ( argv[1], argv + 1 ); + secs = (currticks() - start) / ticks_per_sec(); + + printf ( "%s: %ds\n", argv[0], secs ); + + return rc; +} + +struct command time_command __command = { + .name = "time", + .exec = time_exec, +}; + +static int sleep_exec ( int argc, char **argv ) { + unsigned long start, delay; + + if ( argc == 1 || + !strcmp ( argv[1], "--help" ) || + !strcmp ( argv[1], "-h" )) + { + printf ( "Usage:\n" + " %s <seconds>\n" + "\n" + "Sleep for <seconds> seconds\n", + argv[0] ); + return 1; + } + start = currticks(); + delay = strtoul ( argv[1], NULL, 0 ) * ticks_per_sec(); + while ( ( currticks() - start ) <= delay ) + cpu_nap(); + return 0; +} + +struct command sleep_command __command = { + .name = "sleep", + .exec = sleep_exec, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/editstring.c b/contrib/syslinux-4.02/gpxe/src/hci/editstring.c new file mode 100644 index 0000000..648f338 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/editstring.c @@ -0,0 +1,192 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <assert.h> +#include <string.h> +#include <gpxe/keys.h> +#include <gpxe/editstring.h> + +/** @file + * + * Editable strings + * + */ + +static void insert_delete ( struct edit_string *string, size_t delete_len, + const char *insert_text ) + __attribute__ (( nonnull (1) )); +static void insert_character ( struct edit_string *string, + unsigned int character ) __nonnull; +static void delete_character ( struct edit_string *string ) __nonnull; +static void backspace ( struct edit_string *string ) __nonnull; +static void kill_eol ( struct edit_string *string ) __nonnull; + +/** + * Insert and/or delete text within an editable string + * + * @v string Editable string + * @v delete_len Length of text to delete from current cursor position + * @v insert_text Text to insert at current cursor position, or NULL + */ +static void insert_delete ( struct edit_string *string, size_t delete_len, + const char *insert_text ) { + size_t old_len, max_delete_len, insert_len, max_insert_len, new_len; + + /* Calculate lengths */ + old_len = strlen ( string->buf ); + assert ( string->cursor <= old_len ); + max_delete_len = ( old_len - string->cursor ); + if ( delete_len > max_delete_len ) + delete_len = max_delete_len; + insert_len = ( insert_text ? strlen ( insert_text ) : 0 ); + max_insert_len = ( ( string->len - 1 ) - ( old_len - delete_len ) ); + if ( insert_len > max_insert_len ) + insert_len = max_insert_len; + new_len = ( old_len - delete_len + insert_len ); + + /* Fill in edit history */ + string->mod_start = string->cursor; + string->mod_end = ( ( new_len > old_len ) ? new_len : old_len ); + + /* Move data following the cursor */ + memmove ( ( string->buf + string->cursor + insert_len ), + ( string->buf + string->cursor + delete_len ), + ( max_delete_len + 1 - delete_len ) ); + + /* Copy inserted text to cursor position */ + memcpy ( ( string->buf + string->cursor ), insert_text, insert_len ); + string->cursor += insert_len; +} + +/** + * Insert character at current cursor position + * + * @v string Editable string + * @v character Character to insert + */ +static void insert_character ( struct edit_string *string, + unsigned int character ) { + char insert_text[2] = { character, '\0' }; + insert_delete ( string, 0, insert_text ); +} + +/** + * Delete character at current cursor position + * + * @v string Editable string + */ +static void delete_character ( struct edit_string *string ) { + insert_delete ( string, 1, NULL ); +} + +/** + * Delete character to left of current cursor position + * + * @v string Editable string + */ +static void backspace ( struct edit_string *string ) { + if ( string->cursor > 0 ) { + string->cursor--; + delete_character ( string ); + } +} + +/** + * Delete to end of line + * + * @v string Editable string + */ +static void kill_eol ( struct edit_string *string ) { + insert_delete ( string, ~( ( size_t ) 0 ), NULL ); +} + +/** + * Edit editable string + * + * @v string Editable string + * @v key Key pressed by user + * @ret key Key returned to application, or zero + * + * Handles keypresses and updates the content of the editable string. + * Basic line editing facilities (delete/insert/cursor) are supported. + * If edit_string() understands and uses the keypress it will return + * zero, otherwise it will return the original key. + * + * This function does not update the display in any way. + * + * The string's edit history will be updated to allow the caller to + * efficiently bring the display into sync with the string content. + */ +int edit_string ( struct edit_string *string, int key ) { + int retval = 0; + size_t len = strlen ( string->buf ); + + /* Prepare edit history */ + string->last_cursor = string->cursor; + string->mod_start = string->cursor; + string->mod_end = string->cursor; + + /* Interpret key */ + if ( ( key >= 0x20 ) && ( key <= 0x7e ) ) { + /* Printable character; insert at current position */ + insert_character ( string, key ); + } else switch ( key ) { + case KEY_BACKSPACE: + /* Backspace */ + backspace ( string ); + break; + case KEY_DC: + case CTRL_D: + /* Delete character */ + delete_character ( string ); + break; + case CTRL_K: + /* Delete to end of line */ + kill_eol ( string ); + break; + case KEY_HOME: + case CTRL_A: + /* Start of line */ + string->cursor = 0; + break; + case KEY_END: + case CTRL_E: + /* End of line */ + string->cursor = len; + break; + case KEY_LEFT: + case CTRL_B: + /* Cursor left */ + if ( string->cursor > 0 ) + string->cursor--; + break; + case KEY_RIGHT: + case CTRL_F: + /* Cursor right */ + if ( string->cursor < len ) + string->cursor++; + break; + default: + retval = key; + break; + } + + return retval; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/alert.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/alert.c new file mode 100644 index 0000000..00e959a --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/alert.c @@ -0,0 +1,18 @@ +#include <curses.h> +#include <stdio.h> + +/** @file + * + * MuCurses alert functions + * + */ + +/** + * Audible signal + * + * @ret rc return status code + */ +int beep ( void ) { + printf("\a"); + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/ansi_screen.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/ansi_screen.c new file mode 100644 index 0000000..51fc7c9 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/ansi_screen.c @@ -0,0 +1,74 @@ +#include <stdio.h> +#include <curses.h> +#include <console.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +static void ansiscr_reset(struct _curses_screen *scr) __nonnull; +static void ansiscr_movetoyx(struct _curses_screen *scr, + unsigned int y, unsigned int x) __nonnull; +static void ansiscr_putc(struct _curses_screen *scr, chtype c) __nonnull; + +unsigned short _COLS = 80; +unsigned short _LINES = 24; + +static void ansiscr_reset ( struct _curses_screen *scr ) { + /* Reset terminal attributes and clear screen */ + scr->attrs = 0; + scr->curs_x = 0; + scr->curs_y = 0; + printf ( "\033[0m" ); +} + +static void ansiscr_movetoyx ( struct _curses_screen *scr, + unsigned int y, unsigned int x ) { + if ( ( x != scr->curs_x ) || ( y != scr->curs_y ) ) { + /* ANSI escape sequence to update cursor position */ + printf ( "\033[%d;%dH", ( y + 1 ), ( x + 1 ) ); + scr->curs_x = x; + scr->curs_y = y; + } +} + +static void ansiscr_putc ( struct _curses_screen *scr, chtype c ) { + unsigned int character = ( c & A_CHARTEXT ); + attr_t attrs = ( c & ( A_ATTRIBUTES | A_COLOR ) ); + int bold = ( attrs & A_BOLD ); + attr_t cpair = PAIR_NUMBER ( attrs ); + short fcol; + short bcol; + + /* Update attributes if changed */ + if ( attrs != scr->attrs ) { + scr->attrs = attrs; + pair_content ( cpair, &fcol, &bcol ); + /* ANSI escape sequence to update character attributes */ + printf ( "\033[0;%d;3%d;4%dm", ( bold ? 1 : 22 ), fcol, bcol ); + } + + /* Print the actual character */ + putchar ( character ); + + /* Update expected cursor position */ + if ( ++(scr->curs_x) == _COLS ) { + scr->curs_x = 0; + ++scr->curs_y; + } +} + +static int ansiscr_getc ( struct _curses_screen *scr __unused ) { + return getchar(); +} + +static bool ansiscr_peek ( struct _curses_screen *scr __unused ) { + return iskey(); +} + +SCREEN _ansi_screen = { + .init = ansiscr_reset, + .exit = ansiscr_reset, + .movetoyx = ansiscr_movetoyx, + .putc = ansiscr_putc, + .getc = ansiscr_getc, + .peek = ansiscr_peek, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/clear.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/clear.c new file mode 100644 index 0000000..79b296c --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/clear.c @@ -0,0 +1,90 @@ +#include <curses.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * MuCurses clearing functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Clear a window to the bottom from current cursor position + * + * @v *win subject window + * @ret rc return status code + */ +int wclrtobot ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + do { + _wputc( win, ' ', WRAP ); + } while ( win->curs_y + win->curs_x ); + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Clear a window to the end of the current line + * + * @v *win subject window + * @ret rc return status code + */ +int wclrtoeol ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + while ( ( win->curs_y - pos.y ) == 0 ) { + _wputc( win, ' ', WRAP ); + } + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Delete character under the cursor in a window + * + * @v *win subject window + * @ret rc return status code + */ +int wdelch ( WINDOW *win ) { + _wputc( win, ' ', NOWRAP ); + _wcursback( win ); + + return OK; +} + +/** + * Delete line under a window's cursor + * + * @v *win subject window + * @ret rc return status code + */ +int wdeleteln ( WINDOW *win ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + /* let's just set the cursor to the beginning of the line and + let wclrtoeol do the work :) */ + wmove( win, win->curs_y, 0 ); + wclrtoeol( win ); + _restore_curs_pos( win, &pos ); + return OK; +} + +/** + * Completely clear a window + * + * @v *win subject window + * @ret rc return status code + */ +int werase ( WINDOW *win ) { + wmove( win, 0, 0 ); + wclrtobot( win ); + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/colour.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/colour.c new file mode 100644 index 0000000..c1359c8 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/colour.c @@ -0,0 +1,66 @@ +#include <curses.h> + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct colour_pair { + short fcol; + short bcol; +}; + +static struct colour_pair cpairs[COLOUR_PAIRS] = { + [0] = { COLOUR_WHITE, COLOUR_BLACK }, +}; + +/** + * Identify the RGB components of a given colour value + * + * @v colour colour value + * @v *red address to store red component + * @v *green address to store green component + * @v *blue address to store blue component + * @ret rc return status code + */ +int colour_content ( short colour, short *red, short *green, short *blue ) { + *red = ( ( colour & COLOUR_RED ) ? 1 : 0 ); + *green = ( ( colour & COLOUR_GREEN ) ? 1 : 0 ); + *blue = ( ( colour & COLOUR_BLUE ) ? 1 : 0 ); + return OK; +} + +/** + * Initialise colour pair + * + * @v pair colour pair number + * @v fcol foreground colour + * @v bcol background colour + */ +int init_pair ( short pair, short fcol, short bcol ) { + struct colour_pair *cpair; + + if ( ( pair < 1 ) || ( pair >= COLOUR_PAIRS ) ) + return ERR; + + cpair = &cpairs[pair]; + cpair->fcol = fcol; + cpair->bcol = bcol; + return OK; +} + +/** + * Get colours of colour pair + * + * @v pair colour pair number + * @ret fcol foreground colour + * @ret bcol background colour + */ +int pair_content ( short pair, short *fcol, short *bcol ) { + struct colour_pair *cpair; + + if ( ( pair < 0 ) || ( pair >= COLOUR_PAIRS ) ) + return ERR; + + cpair = &cpairs[pair]; + *fcol = cpair->fcol; + *bcol = cpair->bcol; + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/cursor.h b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/cursor.h new file mode 100644 index 0000000..16b7d27 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/cursor.h @@ -0,0 +1,37 @@ +#ifndef CURSOR_H +#define CURSOR_H + +/** @file + * + * MuCurses cursor implementation specific header file + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +struct cursor_pos { + unsigned int y, x; +}; + +/** + * Restore cursor position from encoded backup variable + * + * @v *win window on which to operate + * @v *pos pointer to struct in which original cursor position is stored + */ +static inline void _restore_curs_pos ( WINDOW *win, struct cursor_pos *pos ) { + wmove ( win, pos->y, pos->x ); +} + +/** + * Store cursor position for later restoration + * + * @v *win window on which to operate + * @v *pos pointer to struct in which to store cursor position + */ +static inline void _store_curs_pos ( WINDOW *win, struct cursor_pos *pos ) { + pos->y = win->curs_y; + pos->x = win->curs_x; +} + +#endif /* CURSOR_H */ diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/edging.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/edging.c new file mode 100644 index 0000000..eccd324 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/edging.c @@ -0,0 +1,111 @@ +#include <curses.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * MuCurses edging functions + * + */ + +/** + * Draw borders from single-byte characters and renditions around a + * window + * + * @v *win window to be bordered + * @v verch vertical chtype + * @v horch horizontal chtype + * @ret rc return status code + */ +int box ( WINDOW *win, chtype verch, chtype horch ) { + chtype corner = '+' | win->attrs; /* default corner character */ + return wborder( win, verch, verch, horch, horch, + corner, corner, corner, corner ); +} + +/** + * Draw borders from single-byte characters and renditions around a + * window + * + * @v *win window to be bordered + * @v ls left side + * @v rs right side + * @v ts top + * @v bs bottom + * @v tl top left corner + * @v tr top right corner + * @v bl bottom left corner + * @v br bottom right corner + * @ret rc return status code + */ +int wborder ( WINDOW *win, chtype ls, chtype rs, + chtype ts, chtype bs, chtype tl, + chtype tr, chtype bl, chtype br ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + wmove(win,0,0); + + _wputch(win,tl,WRAP); + while ( ( win->width - 1 ) - win->curs_x ) { + _wputch(win,ts,WRAP); + } + _wputch(win,tr,WRAP); + + while ( ( win->height - 1 ) - win->curs_y ) { + _wputch(win,ls,WRAP); + wmove(win,win->curs_y,(win->width)-1); + _wputch(win,rs,WRAP); + } + + _wputch(win,bl,WRAP); + while ( ( win->width -1 ) - win->curs_x ) { + _wputch(win,bs,WRAP); + } + _wputch(win,br,NOWRAP); /* do not wrap last char to leave + cursor in last position */ + _restore_curs_pos( win, &pos ); + + return OK; +} + +/** + * Create a horizontal line in a window + * + * @v *win subject window + * @v ch rendition and character + * @v n max number of chars (wide) to render + * @ret rc return status code + */ +int whline ( WINDOW *win, chtype ch, int n ) { + struct cursor_pos pos; + + _store_curs_pos ( win, &pos ); + while ( ( win->curs_x - win->width ) && n-- ) { + _wputch ( win, ch, NOWRAP ); + } + _restore_curs_pos ( win, &pos ); + + return OK; +} + +/** + * Create a vertical line in a window + * + * @v *win subject window + * @v ch rendition and character + * @v n max number of chars (high) to render + * @ret rc return status code + */ +int wvline ( WINDOW *win, chtype ch, int n ) { + struct cursor_pos pos; + + _store_curs_pos ( win, &pos ); + while ( ( win->curs_y - win->height ) && n-- ) { + _wputch ( win, ch, NOWRAP ); + wmove( win, ++(win->curs_y), pos.x); + } + _restore_curs_pos ( win, &pos ); + + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/kb.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/kb.c new file mode 100644 index 0000000..cada729 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/kb.c @@ -0,0 +1,143 @@ +#include <curses.h> +#include <stddef.h> +#include <unistd.h> +#include "mucurses.h" + +/** @file + * + * MuCurses keyboard input handling functions + */ + +#define INPUT_DELAY 200 // half-blocking delay timer resolution (ms) +#define INPUT_DELAY_TIMEOUT 1000 // half-blocking delay timeout + +int m_delay; /* + < 0 : blocking read + 0 : non-blocking read + > 0 : timed blocking read + */ +bool m_echo; +bool m_cbreak; + +static int _wgetc ( WINDOW *win ) { + int timer, c; + + if ( win == NULL ) + return ERR; + + timer = INPUT_DELAY_TIMEOUT; + while ( ! win->scr->peek( win->scr ) ) { + if ( m_delay == 0 ) // non-blocking read + return ERR; + if ( timer > 0 ) { // time-limited blocking read + if ( m_delay > 0 ) + timer -= INPUT_DELAY; + mdelay( INPUT_DELAY ); + } else { return ERR; } // non-blocking read + } + + c = win->scr->getc( win->scr ); + + if ( m_echo && ( c >= 32 && c <= 126 ) ) // printable ASCII characters + _wputch( win, (chtype) ( c | win->attrs ), WRAP ); + + return c; +} + +/** + * Pop a character from the FIFO into a window + * + * @v *win window in which to echo input + * @ret c char from input stream + */ +int wgetch ( WINDOW *win ) { + int c; + + c = _wgetc( win ); + + if ( m_echo ) { + if ( c >= KEY_MIN ) { + switch(c) { + case KEY_LEFT : + case KEY_BACKSPACE : + _wcursback( win ); + wdelch( win ); + break; + default : + beep(); + break; + } + } else { + _wputch( win, (chtype)( c | win->attrs ), WRAP ); + } + } + + return c; +} + +/** + * Read at most n characters from the FIFO into a window + * + * @v *win window in which to echo input + * @v *str pointer to string in which to store result + * @v n maximum number of characters to read into string (inc. NUL) + * @ret rc return status code + */ +int wgetnstr ( WINDOW *win, char *str, int n ) { + char *_str; + int c; + + if ( n == 0 ) { + str = '\0'; + return OK; + } + + _str = str; + + while ( ( c = _wgetc( win ) ) != ERR ) { + /* termination enforcement - don't let us go past the + end of the allocated buffer... */ + if ( n == 0 && ( c >= 32 && c <= 126 ) ) { + _wcursback( win ); + wdelch( win ); + } else { + if ( c >= KEY_MIN ) { + switch(c) { + case KEY_LEFT : + case KEY_BACKSPACE : + _wcursback( win ); + wdelch( win ); + break; + case KEY_ENTER : + *_str = '\0'; + return OK; + default : + beep(); + break; + } + } + if ( c >= 32 && c <= 126 ) { + *(_str++) = c; n--; + } + } + } + + return ERR; +} + + +/** + * + */ +int echo ( void ) { + m_echo = TRUE; + return OK; +} + +/** + * + */ +int noecho ( void ) { + m_echo = FALSE; + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/mucurses.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/mucurses.c new file mode 100644 index 0000000..087ebcc --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/mucurses.c @@ -0,0 +1,147 @@ +#include <console.h> +#include <curses.h> +#include "mucurses.h" + +/** @file + * + * MuCurses core functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +static void _wupdcurs ( WINDOW *win ) __nonnull; +void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull; +void _wputc ( WINDOW *win, char c, int wrap ) __nonnull; +void _wcursback ( WINDOW *win ) __nonnull; +void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull; +void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull; +int wmove ( WINDOW *win, int y, int x ) __nonnull; + +WINDOW _stdscr = { + .attrs = A_DEFAULT, + .ori_y = 0, + .ori_x = 0, + .curs_y = 0, + .curs_x = 0, + .scr = &_ansi_screen, +}; + +/* + * Primitives + */ + +/** + * Update cursor position + * + * @v *win window in which to update position + */ +static void _wupdcurs ( WINDOW *win ) { + win->scr->movetoyx ( win->scr, win->ori_y + win->curs_y, + win->ori_x + win->curs_x ); +} + +/** + * Write a single character rendition to a window + * + * @v *win window in which to write + * @v ch character rendition to write + * @v wrap wrap "switch" + */ +void _wputch ( WINDOW *win, chtype ch, int wrap ) { + /* make sure we set the screen cursor to the right position + first! */ + _wupdcurs(win); + win->scr->putc(win->scr, ch); + if ( ++(win->curs_x) - win->width == 0 ) { + if ( wrap == WRAP ) { + win->curs_x = 0; + /* specification says we should really scroll, + but we have no buffer to scroll with, so we + can only overwrite back at the beginning of + the window */ + if ( ++(win->curs_y) - win->height == 0 ) + win->curs_y = 0; + } else { + (win->curs_x)--; + } + } +} + +/** + * Write a single character to a window + * + * @v *win window in which to write + * @v c character rendition to write + * @v wrap wrap "switch" + */ +void _wputc ( WINDOW *win, char c, int wrap ) { + _wputch ( win, ( c | win->attrs ), wrap ); +} + +/** + * Retreat the cursor back one position (useful for a whole host of + * ops) + * + * @v *win window in which to retreat + */ +void _wcursback ( WINDOW *win ) { + if ( win->curs_x == 0 ) { + if ( win->curs_y == 0 ) + win->curs_y = win->height - 1; + win->curs_x = win->width = 1; + } else { + win->curs_x--; + } + + _wupdcurs(win); +} + +/** + * Write a chtype string to a window + * + * @v *win window in which to write + * @v *chstr chtype string + * @v wrap wrap "switch" + * @v n write at most n chtypes + */ +void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) { + for ( ; *chstr && n-- ; chstr++ ) { + _wputch(win,*chstr,wrap); + } +} + +/** + * Write a standard c-style string to a window + * + * @v *win window in which to write + * @v *str string + * @v wrap wrap "switch" + * @v n write at most n chars from *str + */ +void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) { + for ( ; *str && n-- ; str++ ) { + _wputc ( win, *str, wrap ); + } +} + +/** + * Move a window's cursor to the specified position + * + * @v *win window to be operated on + * @v y Y position + * @v x X position + * @ret rc return status code + */ +int wmove ( WINDOW *win, int y, int x ) { + /* chech for out-of-bounds errors */ + if ( ( (unsigned)y >= win->height ) || + ( (unsigned)x >= win->width ) ) { + return ERR; + } + + win->curs_y = y; + win->curs_x = x; + _wupdcurs(win); + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/mucurses.h b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/mucurses.h new file mode 100644 index 0000000..7ac1086 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/mucurses.h @@ -0,0 +1,23 @@ +#ifndef _MUCURSES_H +#define _MUCURSES_H + +/** @file + * + * MuCurses core implementation specific header file + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#define WRAP 0 +#define NOWRAP 1 + +extern SCREEN _ansi_screen; + +extern void _wputch ( WINDOW *win, chtype ch, int wrap ) __nonnull; +extern void _wputc ( WINDOW *win, char c, int wrap ) __nonnull; +extern void _wputchstr ( WINDOW *win, const chtype *chstr, int wrap, int n ) __nonnull; +extern void _wputstr ( WINDOW *win, const char *str, int wrap, int n ) __nonnull; +extern void _wcursback ( WINDOW *win ) __nonnull; + +#endif /* _MUCURSES_H */ diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/print.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/print.c new file mode 100644 index 0000000..1608c0a --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/print.c @@ -0,0 +1,86 @@ +#include <curses.h> +#include <stdio.h> +#include <stddef.h> +#include <gpxe/vsprintf.h> +#include "mucurses.h" + +/** @file + * + * MuCurses printing functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Add a single-byte character and rendition to a window and advance + * the cursor + * + * @v *win window to be rendered in + * @v ch character to be added at cursor + * @ret rc return status code + */ +int waddch ( WINDOW *win, const chtype ch ) { + _wputch( win, ch, WRAP ); + return OK; +} + +/** + * Add string of single-byte characters to a window + * + * @v *win window to be rendered in + * @v *str standard c-style string + * @v n max number of chars from string to render + * @ret rc return status code + */ +int waddnstr ( WINDOW *win, const char *str, int n ) { + _wputstr( win, str, WRAP, n ); + return OK; +} + +struct printw_context { + struct printf_context ctx; + WINDOW *win; +}; + +static void _printw_handler ( struct printf_context *ctx, unsigned int c ) { + struct printw_context *wctx = + container_of ( ctx, struct printw_context, ctx ); + + _wputch( wctx->win, c | wctx->win->attrs, WRAP ); +} + +/** + * Print formatted output in a window + * + * @v *win subject window + * @v *fmt formatted string + * @v varglist argument list + * @ret rc return status code + */ +int vw_printw ( WINDOW *win, const char *fmt, va_list varglist ) { + struct printw_context wctx; + + wctx.win = win; + wctx.ctx.handler = _printw_handler; + vcprintf ( &(wctx.ctx), fmt, varglist ); + return OK; +} + +/** + * Print formatted output to a window + * + * @v *win subject window + * @v *fmt formatted string + * @v ... string arguments + * @ret rc return status code + */ +int wprintw ( WINDOW *win, const char *fmt, ... ) { + va_list args; + int i; + + va_start ( args, fmt ); + i = vw_printw ( win, fmt, args ); + va_end ( args ); + return i; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/print_nadv.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/print_nadv.c new file mode 100644 index 0000000..ee472e6 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/print_nadv.c @@ -0,0 +1,26 @@ +#include <curses.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * MuCurses printing functions (no cursor advance) + * + */ + +/** + * Add string of single-byte characters and renditions to a window + * + * @v *win window to be rendered in + * @v *chstr pointer to first chtype in "string" + * @v n max number of chars from chstr to render + * @ret rc return status code + */ +int waddchnstr ( WINDOW *win, const chtype *chstr, int n ) { + struct cursor_pos pos; + + _store_curs_pos( win, &pos ); + _wputchstr( win, chstr, NOWRAP, n ); + _restore_curs_pos( win, &pos ); + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/slk.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/slk.c new file mode 100644 index 0000000..600658e --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/slk.c @@ -0,0 +1,363 @@ +#include <curses.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "mucurses.h" +#include "cursor.h" + +/** @file + * + * Soft label key functions + */ + +#define MIN_SPACE_SIZE 2 + +#define SLK_MAX_LABEL_LEN 8 + +#define SLK_MAX_NUM_LABELS 12 + +#define SLK_MAX_NUM_SPACES 2 + +struct _softlabel { + // label string + char label[SLK_MAX_LABEL_LEN]; + /* Format of soft label + 0: left justify + 1: centre justify + 2: right justify + */ + unsigned int fmt; +}; + +struct _softlabelkeys { + struct _softlabel fkeys[SLK_MAX_NUM_LABELS]; + attr_t attrs; + /* Soft label layout format + 0: 3-2-3 + 1: 4-4 + 2: 4-4-4 + 3: 4-4-4 with index line + */ + unsigned int fmt; + unsigned int max_label_len; + unsigned int maj_space_len; + unsigned int num_labels; + unsigned int num_spaces; + unsigned int spaces[SLK_MAX_NUM_SPACES]; + struct cursor_pos saved_cursor; + attr_t saved_attrs; + short saved_pair; +}; + +static struct _softlabelkeys *slks; + +/* + I either need to break the primitives here, or write a collection of + functions specifically for SLKs that directly access the screen + functions - since this technically isn't part of stdscr, I think + this should be ok... + */ + +static void _enter_slk ( void ) { + _store_curs_pos ( stdscr, &slks->saved_cursor ); + wattr_get ( stdscr, &slks->saved_attrs, &slks->saved_pair, NULL ); + LINES++; + wmove ( stdscr, LINES, 0 ); + wattrset ( stdscr, slks->attrs ); +} + +static void _leave_slk ( void ) { + LINES--; + wattr_set ( stdscr, slks->saved_attrs, slks->saved_pair, NULL ); + _restore_curs_pos ( stdscr, &slks->saved_cursor ); +} + +static void _print_label ( struct _softlabel sl ) { + int space_ch; + char str[SLK_MAX_LABEL_LEN + 1]; + + assert ( slks->max_label_len <= SLK_MAX_LABEL_LEN ); + space_ch = ' '; + + // protect against gaps in the soft label keys array + if ( sl.label == NULL ) { + memset( str, space_ch, (size_t)(slks->max_label_len) ); + } else { + /* we need to pad the label with varying amounts of leading + pad depending on the format of the label */ + if ( sl.fmt == 1 ) { + memset( str, space_ch, + (size_t)(slks->max_label_len + - strlen(sl.label)) / 2 ); + } + if ( sl.fmt == 2 ) { + memset( str, space_ch, + (size_t)(slks->max_label_len + - strlen(sl.label)) ); + } + strcat(str,sl.label); + + // post-padding + memset(str+strlen(str), space_ch, + (size_t)(slks->max_label_len - strlen(str)) ); + } + + // print the formatted label + _wputstr ( stdscr, str, NOWRAP, slks->max_label_len ); +} + +/** + * Return the attribute used for the soft function keys + * + * @ret attrs the current attributes of the soft function keys + */ +attr_t slk_attr ( void ) { + return ( slks == NULL ? 0 : slks->attrs ); +} + +/** + * Turn off soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attroff ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs &= ~( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Turn on soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attron ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs |= ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Set soft function key attributes + * + * @v attrs attribute bit mask + * @ret rc return status code + */ +int slk_attrset ( const chtype attrs ) { + if ( slks == NULL ) + return ERR; + slks->attrs = ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Turn off soft function key attributes + * + * @v attrs attribute bit mask + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_off ( const attr_t attrs, void *opts __unused ) { + return slk_attroff( attrs ); +} + +/** + * Turn on soft function key attributes + * + * @v attrs attribute bit mask + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_on ( attr_t attrs, void *opts __unused ) { + return slk_attron( attrs ); +} + +/** + * Set soft function key attributes + * + * @v attrs attribute bit mask + * @v colour_pair_number colour pair integer + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int slk_attr_set ( const attr_t attrs, short colour_pair_number, + void *opts __unused ) { + if ( slks == NULL ) + return ERR; + + if ( ( unsigned short )colour_pair_number > COLORS ) + return ERR; + + slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) | + ( attrs & A_ATTRIBUTES ); + return OK; +} + +/** + * Clear the soft function key labels from the screen + * + * @ret rc return status code + */ +int slk_clear ( void ) { + if ( slks == NULL ) + return ERR; + + _enter_slk(); + wclrtoeol ( stdscr ); + _leave_slk(); + + return OK; +} + +/** + * Set soft label colour pair + */ +int slk_colour ( short colour_pair_number ) { + if ( slks == NULL ) + return ERR; + if ( ( unsigned short )colour_pair_number > COLORS ) + return ERR; + + slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) + | ( slks->attrs & A_ATTRIBUTES ); + + return OK; +} + +/** + * Initialise the soft function keys + * + * @v fmt format of keys + * @ret rc return status code + */ +int slk_init ( int fmt ) { + unsigned short nmaj, nmin, nblocks, available_width; + + if ( (unsigned)fmt > 3 ) { + return ERR; + } + + /* There seems to be no API call to free this data structure... */ + if ( ! slks ) + slks = calloc(1,sizeof(*slks)); + if ( ! slks ) + return ERR; + + slks->attrs = A_DEFAULT; + slks->fmt = fmt; + switch(fmt) { + case 0: + nblocks = 8; nmaj = 2; nmin = 5; + slks->spaces[0] = 2; slks->spaces[1] = 4; + break; + case 1: + nblocks = 8; nmaj = 1; nmin = 6; + slks->spaces[0] = 3; + break; + case 2: + // same allocations as format 3 + case 3: + nblocks = 12; nmaj = 2; nmin = 9; + slks->spaces[0] = 3; slks->spaces[1] = 7; + break; + default: + nblocks = 0; nmaj = 0; nmin = 0; + break; + } + + // determine maximum label length and major space size + available_width = COLS - ( ( MIN_SPACE_SIZE * nmaj ) + nmin ); + slks->max_label_len = available_width / nblocks; + slks->maj_space_len = MIN_SPACE_SIZE + + ( available_width % nblocks ) / nmaj; + slks->num_spaces = nmaj; + slks->num_labels = nblocks; + + // strip a line from the screen + LINES -= 1; + + return OK; +} + +/** + * Return the label for the specified soft key + * + * @v labnum soft key identifier + * @ret label return label + */ +char* slk_label ( int labnum ) { + if ( slks == NULL ) + return NULL; + + return slks->fkeys[labnum].label; +} + +/** + * Restore soft function key labels to the screen + * + * @ret rc return status code + */ +int slk_restore ( void ) { + unsigned int i, j, pos_x, + *next_space, *last_space; + chtype space_ch; + + if ( slks == NULL ) + return ERR; + + pos_x = 0; + + _enter_slk(); + + space_ch = (chtype)' ' | slks->attrs; + next_space = &(slks->spaces[0]); + last_space = &(slks->spaces[slks->num_spaces-1]); + + for ( i = 0; i < slks->num_labels ; i++ ) { + _print_label( slks->fkeys[i] ); + pos_x += slks->max_label_len; + + if ( i == *next_space ) { + for ( j = 0; j < slks->maj_space_len; j++, pos_x++ ) + _wputch ( stdscr, space_ch, NOWRAP ); + if ( next_space < last_space ) + next_space++; + } else { + if ( pos_x < COLS ) + _wputch ( stdscr, space_ch, NOWRAP ); + pos_x++; + } + } + + _leave_slk(); + + return OK; +} + +/** + * Configure specified soft key + * + * @v labnum soft label position to configure + * @v *label string to use as soft key label + * @v fmt justification format of label + * @ret rc return status code + */ +int slk_set ( int labnum, const char *label, int fmt ) { + if ( slks == NULL ) + return ERR; + if ( (unsigned short)labnum >= slks->num_labels ) + return ERR; + if ( (unsigned short)fmt >= 3 ) + return ERR; + + strncpy(slks->fkeys[labnum].label, label, + sizeof(slks->fkeys[labnum].label)); + slks->fkeys[labnum].fmt = fmt; + + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/widgets/editbox.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/widgets/editbox.c new file mode 100644 index 0000000..ee7d609 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/widgets/editbox.c @@ -0,0 +1,103 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <string.h> +#include <assert.h> +#include <gpxe/editbox.h> + +/** @file + * + * Editable text box widget + * + */ + +#define EDITBOX_MIN_CHARS 3 + +/** + * Initialise text box widget + * + * @v box Editable text box widget + * @v buf Text buffer + * @v len Size of text buffer + * @v win Containing window + * @v row Row + * @v col Starting column + * @v width Width + * @v flags Flags + */ +void init_editbox ( struct edit_box *box, char *buf, size_t len, + WINDOW *win, unsigned int row, unsigned int col, + unsigned int width, unsigned int flags ) { + memset ( box, 0, sizeof ( *box ) ); + box->string.buf = buf; + box->string.len = len; + box->string.cursor = strlen ( buf ); + box->win = ( win ? win : stdscr ); + box->row = row; + box->col = col; + box->width = width; + box->flags = flags; +} + +/** + * Draw text box widget + * + * @v box Editable text box widget + * + */ +void draw_editbox ( struct edit_box *box ) { + size_t width = box->width; + char buf[ width + 1 ]; + signed int cursor_offset, underflow, overflow, first; + size_t len; + + /* Adjust starting offset so that cursor remains within box */ + cursor_offset = ( box->string.cursor - box->first ); + underflow = ( EDITBOX_MIN_CHARS - cursor_offset ); + overflow = ( cursor_offset - ( width - 1 ) ); + first = box->first; + if ( underflow > 0 ) { + first -= underflow; + if ( first < 0 ) + first = 0; + } else if ( overflow > 0 ) { + first += overflow; + } + box->first = first; + cursor_offset = ( box->string.cursor - first ); + + /* Construct underscore-padded string portion */ + memset ( buf, '_', width ); + buf[width] = '\0'; + len = ( strlen ( box->string.buf ) - first ); + if ( len > width ) + len = width; + if ( box->flags & EDITBOX_STARS ) { + memset ( buf, '*', len ); + } else { + memcpy ( buf, ( box->string.buf + first ), len ); + } + + /* Print box content and move cursor */ + if ( ! box->win ) + box->win = stdscr; + mvwprintw ( box->win, box->row, box->col, "%s", buf ); + wmove ( box->win, box->row, ( box->col + cursor_offset ) ); +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/winattrs.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/winattrs.c new file mode 100644 index 0000000..f549d75 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/winattrs.c @@ -0,0 +1,133 @@ +#include <curses.h> + +/** @file + * + * MuCurses window attribute functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Get the background rendition attributes for a window + * + * @v *win subject window + * @ret ch chtype rendition representation + */ +inline chtype getbkgd ( WINDOW *win ) { + return win->attrs; +} + +/** + * Turn off attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattroff ( WINDOW *win, int attrs ) { + win->attrs &= ~attrs; + return OK; +} + +/** + * Turn on attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattron ( WINDOW *win, int attrs ) { + win->attrs |= attrs; + return OK; +} + +/** + * Set attributes in a window + * + * @v win subject window + * @v attrs attributes to enable + * @ret rc return status code + */ +int wattrset ( WINDOW *win, int attrs ) { + win->attrs = ( attrs | ( win->attrs & A_COLOR ) ); + return OK; +} + +/** + * Get attributes and colour pair information + * + * @v *win window to obtain information from + * @v *attrs address in which to store attributes + * @v *pair address in which to store colour pair + * @v *opts undefined (for future implementation) + * @ret rc return status cude + */ +int wattr_get ( WINDOW *win, attr_t *attrs, short *pair, + void *opts __unused ) { + *attrs = win->attrs & A_ATTRIBUTES; + *pair = PAIR_NUMBER ( win->attrs ); + return OK; +} + +/** + * Turn off attributes in a window + * + * @v *win subject window + * @v attrs attributes to toggle + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_off ( WINDOW *win, attr_t attrs, + void *opts __unused ) { + wattroff( win, attrs ); + return OK; +} + +/** + * Turn on attributes in a window + * + * @v *win subject window + * @v attrs attributes to toggle + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_on ( WINDOW *win, attr_t attrs, + void *opts __unused ) { + wattron( win, attrs ); + return OK; +} + +/** + * Set attributes and colour pair information in a window + * + * @v *win subject window + * @v attrs attributes to set + * @v cpair colour pair to set + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wattr_set ( WINDOW *win, attr_t attrs, short cpair, + void *opts __unused ) { + wattrset( win, attrs | COLOUR_PAIR ( cpair ) ); + return OK; +} + +/** + * Set colour pair for a window + * + * @v *win subject window + * @v colour_pair_number colour pair integer + * @v *opts undefined (for future implementation) + * @ret rc return status code + */ +int wcolour_set ( WINDOW *win, short colour_pair_number, + void *opts __unused ) { + if ( ( unsigned short )colour_pair_number > COLOUR_PAIRS ) + return ERR; + + win->attrs = ( ( win->attrs & A_ATTRIBUTES ) | + COLOUR_PAIR ( colour_pair_number ) ); + return OK; +} + diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/windows.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/windows.c new file mode 100644 index 0000000..63d0af0 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/windows.c @@ -0,0 +1,158 @@ +#include <curses.h> +#include <stddef.h> +#include <stdlib.h> +#include "mucurses.h" + +/** @file + * + * MuCurses windows instance functions + * + */ + +/** + * Delete a window + * + * @v *win pointer to window being deleted + * @ret rc return status code + */ +int delwin ( WINDOW *win ) { + if ( win == NULL ) + return ERR; + + /* I think we should blank the region covered by the window - + ncurses doesn't do this, but they have a buffer, so they + may just be deleting from an offscreen context whereas we + are guaranteed to be deleting something onscreen */ + wmove( win, 0, 0 ); + chtype killch = (chtype)' '; + do { + _wputch( win, killch, WRAP ); + } while ( win->curs_x + win->curs_y ); + + free( win ); + + wmove ( stdscr, 0, 0 ); + + return OK; +} + +/** + * Create a new derived window + * + * @v parent parent window + * @v nlines window height + * @v ncols window width + * @v begin_y window y origin (relative to parent) + * @v begin_x window x origin (relative to parent) + * @ret ptr return pointer to child window + */ +WINDOW *derwin ( WINDOW *parent, int nlines, int ncols, + int begin_y, int begin_x ) { + WINDOW *child; + if ( parent == NULL ) + return NULL; + if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL ) + return NULL; + if ( ( (unsigned)ncols > parent->width ) || + ( (unsigned)nlines > parent->height ) ) + return NULL; + child->ori_y = parent->ori_y + begin_y; + child->ori_x = parent->ori_x + begin_x; + child->height = nlines; + child->width = ncols; + child->parent = parent; + child->scr = parent->scr; + return child; +} + +/** + * Create a duplicate of the specified window + * + * @v orig original window + * @ret ptr pointer to duplicate window + */ +WINDOW *dupwin ( WINDOW *orig ) { + WINDOW *copy; + if ( orig == NULL ) + return NULL; + if ( ( copy = malloc( sizeof( WINDOW ) ) ) == NULL ) + return NULL; + copy->scr = orig->scr; + copy->attrs = orig->attrs; + copy->ori_y = orig->ori_y; + copy->ori_x = orig->ori_x; + copy->curs_y = orig->curs_y; + copy->curs_x = orig->curs_x; + copy->height = orig->height; + copy->width = orig->width; + return copy; +} + +/** + * Move window origin to specified coordinates + * + * @v *win window to move + * @v y Y position + * @v x X position + * @ret rc return status code + */ +int mvwin ( WINDOW *win, int y, int x ) { + if ( win == NULL ) + return ERR; + if ( ( ( (unsigned)y + win->height ) > LINES ) || + ( ( (unsigned)x + win->width ) > COLS ) ) + return ERR; + + win->ori_y = y; + win->ori_x = x; + + return OK; +} + +/** + * Create new WINDOW + * + * @v nlines number of lines + * @v ncols number of columns + * @v begin_y column origin + * @v begin_x line origin + * @ret *win return pointer to new window + */ +WINDOW *newwin ( int nlines, int ncols, int begin_y, int begin_x ) { + WINDOW *win; + if ( ( win = malloc( sizeof(WINDOW) ) ) == NULL ) + return NULL; + if ( ( (unsigned)( begin_y + nlines ) > stdscr->height ) && + ( (unsigned)( begin_x + ncols ) > stdscr->width ) ) + return NULL; + win->ori_y = begin_y; + win->ori_x = begin_x; + win->height = nlines; + win->width = ncols; + win->scr = stdscr->scr; + win->parent = stdscr; + return win; +} + +/** + * Create a new sub-window + * + * @v orig parent window + * @v nlines window height + * @v ncols window width + * @v begin_y window y origin (absolute) + * @v begin_x window x origin (absolute) + * @ret ptr return pointer to child window + */ +WINDOW *subwin ( WINDOW *parent, int nlines, int ncols, + int begin_y, int begin_x ) { + WINDOW *child; + if ( parent == NULL ) + return NULL; + if ( ( child = malloc( sizeof( WINDOW ) ) ) == NULL ) + return NULL; + child = newwin( nlines, ncols, begin_y, begin_x ); + child->parent = parent; + child->scr = parent->scr; + return child; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/mucurses/wininit.c b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/wininit.c new file mode 100644 index 0000000..782e7b5 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/mucurses/wininit.c @@ -0,0 +1,37 @@ +#include <stddef.h> +#include <curses.h> + +/** @file + * + * MuCurses initialisation functions + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Initialise console environment + * + * @ret *win return pointer to stdscr + */ +WINDOW *initscr ( void ) { + /* determine console size */ + /* initialise screen */ + stdscr->scr->init( stdscr->scr ); + stdscr->height = LINES; + stdscr->width = COLS; + move ( 0, 0 ); + return stdscr; +} + +/** + * Finalise console environment + * + */ +int endwin ( void ) { + attrset ( 0 ); + color_set ( 0, NULL ); + mvprintw ( ( LINES - 1 ), 0, "\n" ); + stdscr->scr->exit( stdscr->scr ); + return OK; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/readline.c b/contrib/syslinux-4.02/gpxe/src/hci/readline.c new file mode 100644 index 0000000..e5699d5 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/readline.c @@ -0,0 +1,119 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <console.h> +#include <gpxe/keys.h> +#include <gpxe/editstring.h> +#include <readline/readline.h> + +/** @file + * + * Minimal readline + * + */ + +#define READLINE_MAX 256 + +static void sync_console ( struct edit_string *string ) __nonnull; + +/** + * Synchronise console with edited string + * + * @v string Editable string + */ +static void sync_console ( struct edit_string *string ) { + unsigned int mod_start = string->mod_start; + unsigned int mod_end = string->mod_end; + unsigned int cursor = string->last_cursor; + size_t len = strlen ( string->buf ); + + /* Expand region back to old cursor position if applicable */ + if ( mod_start > string->last_cursor ) + mod_start = string->last_cursor; + + /* Expand region forward to new cursor position if applicable */ + if ( mod_end < string->cursor ) + mod_end = string->cursor; + + /* Backspace to start of region */ + while ( cursor > mod_start ) { + putchar ( '\b' ); + cursor--; + } + + /* Print modified region */ + while ( cursor < mod_end ) { + putchar ( ( cursor >= len ) ? ' ' : string->buf[cursor] ); + cursor++; + } + + /* Backspace to new cursor position */ + while ( cursor > string->cursor ) { + putchar ( '\b' ); + cursor--; + } +} + +/** + * Read line from console + * + * @v prompt Prompt string + * @ret line Line read from console (excluding terminating newline) + * + * The returned line is allocated with malloc(); the caller must + * eventually call free() to release the storage. + */ +char * readline ( const char *prompt ) { + char buf[READLINE_MAX]; + struct edit_string string; + int key; + char *line; + + if ( prompt ) + printf ( "%s", prompt ); + + memset ( &string, 0, sizeof ( string ) ); + string.buf = buf; + string.len = sizeof ( buf ); + buf[0] = '\0'; + + while ( 1 ) { + key = edit_string ( &string, getkey() ); + sync_console ( &string ); + switch ( key ) { + case CR: + case LF: + putchar ( '\n' ); + line = strdup ( buf ); + if ( ! line ) + printf ( "Out of memory\n" ); + return line; + case CTRL_C: + putchar ( '\n' ); + return NULL; + default: + /* Do nothing */ + break; + } + } +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/shell.c b/contrib/syslinux-4.02/gpxe/src/hci/shell.c new file mode 100644 index 0000000..5bedbdc --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/shell.c @@ -0,0 +1,102 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <readline/readline.h> +#include <gpxe/command.h> +#include <gpxe/shell.h> + +/** @file + * + * Minimal command shell + * + */ + +/** The shell prompt string */ +static const char shell_prompt[] = "gPXE> "; + +/** Flag set in order to exit shell */ +static int exit_flag = 0; + +/** "exit" command body */ +static int exit_exec ( int argc, char **argv __unused ) { + + if ( argc == 1 ) { + exit_flag = 1; + } else { + printf ( "Usage: exit\n" + "Exits the command shell\n" ); + } + + return 0; +} + +/** "exit" command definition */ +struct command exit_command __command = { + .name = "exit", + .exec = exit_exec, +}; + +/** "help" command body */ +static int help_exec ( int argc __unused, char **argv __unused ) { + struct command *command; + unsigned int hpos = 0; + + printf ( "\nAvailable commands:\n\n" ); + for_each_table_entry ( command, COMMANDS ) { + hpos += printf ( " %s", command->name ); + if ( hpos > ( 16 * 4 ) ) { + printf ( "\n" ); + hpos = 0; + } else { + while ( hpos % 16 ) { + printf ( " " ); + hpos++; + } + } + } + printf ( "\n\nType \"<command> --help\" for further information\n\n" ); + return 0; +} + +/** "help" command definition */ +struct command help_command __command = { + .name = "help", + .exec = help_exec, +}; + +/** + * Start command shell + * + */ +void shell ( void ) { + char *line; + + exit_flag = 0; + while ( ! exit_flag ) { + line = readline ( shell_prompt ); + if ( line ) { + system ( line ); + free ( line ); + } + } +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/shell_banner.c b/contrib/syslinux-4.02/gpxe/src/hci/shell_banner.c new file mode 100644 index 0000000..b92e08e --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/shell_banner.c @@ -0,0 +1,64 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdio.h> +#include <console.h> +#include <unistd.h> +#include <config/general.h> +#include <gpxe/keys.h> +#include <gpxe/shell_banner.h> + +/** @file + * + * Shell startup banner + * + */ + +/** + * Print shell banner and prompt for shell entry + * + * @ret enter_shell User wants to enter shell + */ +int shell_banner ( void ) { + int enter_shell = 0; + int wait_count; + int key; + + if ( BANNER_TIMEOUT <= 0 ) + return enter_shell; + + printf ( "\nPress Ctrl-B for the gPXE command line..." ); + + /* Wait for key */ + for ( wait_count = 0 ; wait_count < BANNER_TIMEOUT ; wait_count++ ) { + if ( iskey() ) { + key = getchar(); + if ( key == CTRL_B ) + enter_shell = 1; + break; + } + mdelay(100); + } + + /* Clear the "Press Ctrl-B" line */ + printf ( "\r \r" ); + + return enter_shell; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/strerror.c b/contrib/syslinux-4.02/gpxe/src/hci/strerror.c new file mode 100644 index 0000000..94547dd --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/strerror.c @@ -0,0 +1,122 @@ +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <gpxe/errortab.h> + +/** @file + * + * Error descriptions. + * + * The error numbers used by Etherboot are a superset of those defined + * by the PXE specification version 2.1. See errno.h for a listing of + * the error values. + * + * To save space in ROM images, error string tables are optional. Use + * the ERRORMSG_XXX options in config.h to select which error string + * tables you want to include. If an error string table is omitted, + * strerror() will simply return the text "Error 0x<errno>". + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Find error description + * + * @v errno Error number + * @ret errortab Error description, or NULL + */ +static struct errortab * find_error ( int errno ) { + struct errortab *errortab; + + for_each_table_entry ( errortab, ERRORTAB ) { + if ( errortab->errno == errno ) + return errortab; + } + + return NULL; +} + +/** + * Find closest error description + * + * @v errno Error number + * @ret errortab Error description, or NULL + * + * + */ +static struct errortab * find_closest_error ( int errno ) { + struct errortab *errortab; + + /* First, look for an exact match */ + if ( ( errortab = find_error ( errno ) ) != NULL ) + return errortab; + + /* Second, try masking off the gPXE-specific bit and seeing if + * we have an entry for the generic POSIX error message. + */ + if ( ( errortab = find_error ( errno & 0x7f0000ff ) ) != NULL ) + return errortab; + + return NULL; +} + +/** + * Retrieve string representation of error number. + * + * @v errno/rc Error number or return status code + * @ret strerror Pointer to error text + * + * If the error is not found in the linked-in error tables, generates + * a generic "Error 0x<errno>" message. + * + * The pointer returned by strerror() is valid only until the next + * call to strerror(). + * + */ +const char * strerror ( int errno ) { + static char errbuf[64]; + struct errortab *errortab; + + /* Allow for strerror(rc) as well as strerror(errno) */ + if ( errno < 0 ) + errno = -errno; + + /* Find the error description, if one exists */ + errortab = find_closest_error ( errno ); + + /* Construct the error message */ + if ( errortab ) { + snprintf ( errbuf, sizeof ( errbuf ), "%s (%#08x)", + errortab->text, errno ); + } else { + snprintf ( errbuf, sizeof ( errbuf ), "Error %#08x", errno ); + } + + return errbuf; +} + +/* Do not include ERRFILE portion in the numbers in the error table */ +#undef ERRFILE +#define ERRFILE 0 + +/** The most common errors */ +struct errortab common_errors[] __errortab = { + { 0, "No error" }, + { EACCES, "Permission denied" }, + { ECANCELED, "Operation cancelled" }, + { ECONNRESET, "Connection reset" }, + { EINVAL, "Invalid argument" }, + { EIO, "Input/output error" }, + { ENETUNREACH, "Network unreachable" }, + { ENODEV, "No such device" }, + { ENOENT, "File not found" }, + { ENOEXEC, "Not an executable image" }, + { ENOMEM, "Out of memory" }, + { ENOSPC, "No space left on device" }, + { ENOTCONN, "Not connected" }, + { ENOTSUP, "Not supported" }, + { EPERM, "Operation not permitted" }, + { ERANGE, "Out of range" }, + { ETIMEDOUT, "Connection timed out" }, +}; diff --git a/contrib/syslinux-4.02/gpxe/src/hci/tui/login_ui.c b/contrib/syslinux-4.02/gpxe/src/hci/tui/login_ui.c new file mode 100644 index 0000000..b80bf27 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/tui/login_ui.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2009 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** @file + * + * Login UI + * + */ + +#include <string.h> +#include <errno.h> +#include <curses.h> +#include <console.h> +#include <gpxe/settings.h> +#include <gpxe/editbox.h> +#include <gpxe/keys.h> +#include <gpxe/login_ui.h> + +/* Colour pairs */ +#define CPAIR_NORMAL 1 +#define CPAIR_LABEL 2 +#define CPAIR_EDITBOX 3 + +/* Screen layout */ +#define USERNAME_LABEL_ROW 8 +#define USERNAME_ROW 10 +#define PASSWORD_LABEL_ROW 14 +#define PASSWORD_ROW 16 +#define LABEL_COL 36 +#define EDITBOX_COL 30 +#define EDITBOX_WIDTH 20 + +int login_ui ( void ) { + char username[64]; + char password[64]; + struct edit_box username_box; + struct edit_box password_box; + struct edit_box *current_box = &username_box; + int key; + int rc = -EINPROGRESS; + + /* Fetch current setting values */ + fetch_string_setting ( NULL, &username_setting, username, + sizeof ( username ) ); + fetch_string_setting ( NULL, &password_setting, password, + sizeof ( password ) ); + + /* Initialise UI */ + initscr(); + start_color(); + init_pair ( CPAIR_NORMAL, COLOR_WHITE, COLOR_BLACK ); + init_pair ( CPAIR_LABEL, COLOR_WHITE, COLOR_BLACK ); + init_pair ( CPAIR_EDITBOX, COLOR_WHITE, COLOR_BLUE ); + init_editbox ( &username_box, username, sizeof ( username ), NULL, + USERNAME_ROW, EDITBOX_COL, EDITBOX_WIDTH, 0 ); + init_editbox ( &password_box, password, sizeof ( password ), NULL, + PASSWORD_ROW, EDITBOX_COL, EDITBOX_WIDTH, + EDITBOX_STARS ); + + /* Draw initial UI */ + erase(); + color_set ( CPAIR_LABEL, NULL ); + mvprintw ( USERNAME_LABEL_ROW, LABEL_COL, "Username:" ); + mvprintw ( PASSWORD_LABEL_ROW, LABEL_COL, "Password:" ); + color_set ( CPAIR_EDITBOX, NULL ); + draw_editbox ( &username_box ); + draw_editbox ( &password_box ); + + /* Main loop */ + while ( rc == -EINPROGRESS ) { + + draw_editbox ( current_box ); + + key = getkey(); + switch ( key ) { + case KEY_DOWN: + current_box = &password_box; + break; + case KEY_UP: + current_box = &username_box; + break; + case TAB: + current_box = ( ( current_box == &username_box ) ? + &password_box : &username_box ); + break; + case KEY_ENTER: + if ( current_box == &username_box ) { + current_box = &password_box; + } else { + rc = 0; + } + break; + case CTRL_C: + case ESC: + rc = -ECANCELED; + break; + default: + edit_editbox ( current_box, key ); + break; + } + } + + /* Terminate UI */ + color_set ( CPAIR_NORMAL, NULL ); + erase(); + endwin(); + + if ( rc != 0 ) + return rc; + + /* Store settings */ + if ( ( rc = store_setting ( NULL, &username_setting, username, + strlen ( username ) ) ) != 0 ) + return rc; + if ( ( rc = store_setting ( NULL, &password_setting, password, + strlen ( password ) ) ) != 0 ) + return rc; + + return 0; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/tui/settings_ui.c b/contrib/syslinux-4.02/gpxe/src/hci/tui/settings_ui.c new file mode 100644 index 0000000..74ce6af --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/tui/settings_ui.c @@ -0,0 +1,427 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <string.h> +#include <curses.h> +#include <console.h> +#include <gpxe/settings.h> +#include <gpxe/editbox.h> +#include <gpxe/keys.h> +#include <gpxe/settings_ui.h> + +/** @file + * + * Option configuration console + * + */ + +/* Colour pairs */ +#define CPAIR_NORMAL 1 +#define CPAIR_SELECT 2 +#define CPAIR_EDIT 3 +#define CPAIR_ALERT 4 + +/* Screen layout */ +#define TITLE_ROW 1 +#define SETTINGS_LIST_ROW 3 +#define SETTINGS_LIST_COL 1 +#define INFO_ROW 20 +#define ALERT_ROW 20 +#define INSTRUCTION_ROW 22 +#define INSTRUCTION_PAD " " + +/** Layout of text within a setting widget */ +struct setting_row { + char start[0]; + char pad1[1]; + char name[15]; + char pad2[1]; + char value[60]; + char pad3[1]; + char nul; +} __attribute__ (( packed )); + +/** A setting widget */ +struct setting_widget { + /** Settings block */ + struct settings *settings; + /** Configuration setting */ + struct setting *setting; + /** Screen row */ + unsigned int row; + /** Screen column */ + unsigned int col; + /** Edit box widget used for editing setting */ + struct edit_box editbox; + /** Editing in progress flag */ + int editing; + /** Buffer for setting's value */ + char value[256]; /* enough size for a DHCP string */ +}; + +/** Number of registered configuration settings */ +#define NUM_SETTINGS table_num_entries ( SETTINGS ) + +static void load_setting ( struct setting_widget *widget ) __nonnull; +static int save_setting ( struct setting_widget *widget ) __nonnull; +static void init_setting ( struct setting_widget *widget, + struct settings *settings, + struct setting *setting, + unsigned int row, unsigned int col ) __nonnull; +static void draw_setting ( struct setting_widget *widget ) __nonnull; +static int edit_setting ( struct setting_widget *widget, int key ) __nonnull; +static void init_setting_index ( struct setting_widget *widget, + struct settings *settings, + unsigned int index ) __nonnull; +static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull; +static void msg ( unsigned int row, const char *fmt, ... ) __nonnull; +static void valert ( const char *fmt, va_list args ) __nonnull; +static void alert ( const char *fmt, ... ) __nonnull; +static void draw_info_row ( struct setting *setting ) __nonnull; +static int main_loop ( struct settings *settings ) __nonnull; + +/** + * Load setting widget value from configuration settings + * + * @v widget Setting widget + * + */ +static void load_setting ( struct setting_widget *widget ) { + + /* Mark as not editing */ + widget->editing = 0; + + /* Read current setting value */ + if ( fetchf_setting ( widget->settings, widget->setting, + widget->value, sizeof ( widget->value ) ) < 0 ) { + widget->value[0] = '\0'; + } + + /* Initialise edit box */ + init_editbox ( &widget->editbox, widget->value, + sizeof ( widget->value ), NULL, widget->row, + ( widget->col + offsetof ( struct setting_row, value )), + sizeof ( ( ( struct setting_row * ) NULL )->value ), 0); +} + +/** + * Save setting widget value back to configuration settings + * + * @v widget Setting widget + */ +static int save_setting ( struct setting_widget *widget ) { + return storef_setting ( widget->settings, widget->setting, + widget->value ); +} + +/** + * Initialise setting widget + * + * @v widget Setting widget + * @v settings Settings block + * @v setting Configuration setting + * @v row Screen row + * @v col Screen column + */ +static void init_setting ( struct setting_widget *widget, + struct settings *settings, + struct setting *setting, + unsigned int row, unsigned int col ) { + + /* Initialise widget structure */ + memset ( widget, 0, sizeof ( *widget ) ); + widget->settings = settings; + widget->setting = setting; + widget->row = row; + widget->col = col; + + /* Read current setting value */ + load_setting ( widget ); +} + +/** + * Draw setting widget + * + * @v widget Setting widget + */ +static void draw_setting ( struct setting_widget *widget ) { + struct setting_row row; + unsigned int len; + unsigned int curs_col; + char *value; + + /* Fill row with spaces */ + memset ( &row, ' ', sizeof ( row ) ); + row.nul = '\0'; + + /* Construct dot-padded name */ + memset ( row.name, '.', sizeof ( row.name ) ); + len = strlen ( widget->setting->name ); + if ( len > sizeof ( row.name ) ) + len = sizeof ( row.name ); + memcpy ( row.name, widget->setting->name, len ); + + /* Construct space-padded value */ + value = widget->value; + if ( ! *value ) + value = "<not specified>"; + len = strlen ( value ); + if ( len > sizeof ( row.value ) ) + len = sizeof ( row.value ); + memcpy ( row.value, value, len ); + curs_col = ( widget->col + offsetof ( typeof ( row ), value ) + + len ); + + /* Print row */ + mvprintw ( widget->row, widget->col, "%s", row.start ); + move ( widget->row, curs_col ); + if ( widget->editing ) + draw_editbox ( &widget->editbox ); +} + +/** + * Edit setting widget + * + * @v widget Setting widget + * @v key Key pressed by user + * @ret key Key returned to application, or zero + */ +static int edit_setting ( struct setting_widget *widget, int key ) { + widget->editing = 1; + return edit_editbox ( &widget->editbox, key ); +} + +/** + * Initialise setting widget by index + * + * @v widget Setting widget + * @v settings Settings block + * @v index Index of setting with settings list + */ +static void init_setting_index ( struct setting_widget *widget, + struct settings *settings, + unsigned int index ) { + struct setting *all_settings = table_start ( SETTINGS ); + + init_setting ( widget, settings, &all_settings[index], + ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL ); +} + +/** + * Print message centred on specified row + * + * @v row Row + * @v fmt printf() format string + * @v args printf() argument list + */ +static void vmsg ( unsigned int row, const char *fmt, va_list args ) { + char buf[COLS]; + size_t len; + + len = vsnprintf ( buf, sizeof ( buf ), fmt, args ); + mvprintw ( row, ( ( COLS - len ) / 2 ), "%s", buf ); +} + +/** + * Print message centred on specified row + * + * @v row Row + * @v fmt printf() format string + * @v .. printf() arguments + */ +static void msg ( unsigned int row, const char *fmt, ... ) { + va_list args; + + va_start ( args, fmt ); + vmsg ( row, fmt, args ); + va_end ( args ); +} + +/** + * Clear message on specified row + * + * @v row Row + */ +static void clearmsg ( unsigned int row ) { + move ( row, 0 ); + clrtoeol(); +} + +/** + * Print alert message + * + * @v fmt printf() format string + * @v args printf() argument list + */ +static void valert ( const char *fmt, va_list args ) { + clearmsg ( ALERT_ROW ); + color_set ( CPAIR_ALERT, NULL ); + vmsg ( ALERT_ROW, fmt, args ); + sleep ( 2 ); + color_set ( CPAIR_NORMAL, NULL ); + clearmsg ( ALERT_ROW ); +} + +/** + * Print alert message + * + * @v fmt printf() format string + * @v ... printf() arguments + */ +static void alert ( const char *fmt, ... ) { + va_list args; + + va_start ( args, fmt ); + valert ( fmt, args ); + va_end ( args ); +} + +/** + * Draw title row + */ +static void draw_title_row ( void ) { + attron ( A_BOLD ); + msg ( TITLE_ROW, "gPXE option configuration console" ); + attroff ( A_BOLD ); +} + +/** + * Draw information row + * + * @v setting Current configuration setting + */ +static void draw_info_row ( struct setting *setting ) { + clearmsg ( INFO_ROW ); + attron ( A_BOLD ); + msg ( INFO_ROW, "%s - %s", setting->name, setting->description ); + attroff ( A_BOLD ); +} + +/** + * Draw instruction row + * + * @v editing Editing in progress flag + */ +static void draw_instruction_row ( int editing ) { + clearmsg ( INSTRUCTION_ROW ); + if ( editing ) { + msg ( INSTRUCTION_ROW, + "Enter - accept changes" INSTRUCTION_PAD + "Ctrl-C - discard changes" ); + } else { + msg ( INSTRUCTION_ROW, + "Ctrl-X - exit configuration utility" ); + } +} + +static int main_loop ( struct settings *settings ) { + struct setting_widget widget; + unsigned int current = 0; + unsigned int next; + int i; + int key; + int rc; + + /* Print initial screen content */ + draw_title_row(); + color_set ( CPAIR_NORMAL, NULL ); + for ( i = ( NUM_SETTINGS - 1 ) ; i >= 0 ; i-- ) { + init_setting_index ( &widget, settings, i ); + draw_setting ( &widget ); + } + + while ( 1 ) { + /* Redraw information and instruction rows */ + draw_info_row ( widget.setting ); + draw_instruction_row ( widget.editing ); + + /* Redraw current setting */ + color_set ( ( widget.editing ? CPAIR_EDIT : CPAIR_SELECT ), + NULL ); + draw_setting ( &widget ); + color_set ( CPAIR_NORMAL, NULL ); + + key = getkey(); + if ( widget.editing ) { + key = edit_setting ( &widget, key ); + switch ( key ) { + case CR: + case LF: + if ( ( rc = save_setting ( &widget ) ) != 0 ) { + alert ( " Could not set %s: %s ", + widget.setting->name, + strerror ( rc ) ); + } + /* Fall through */ + case CTRL_C: + load_setting ( &widget ); + break; + default: + /* Do nothing */ + break; + } + } else { + next = current; + switch ( key ) { + case KEY_DOWN: + if ( next < ( NUM_SETTINGS - 1 ) ) + next++; + break; + case KEY_UP: + if ( next > 0 ) + next--; + break; + case CTRL_X: + return 0; + default: + edit_setting ( &widget, key ); + break; + } + if ( next != current ) { + draw_setting ( &widget ); + init_setting_index ( &widget, settings, next ); + current = next; + } + } + } + +} + +int settings_ui ( struct settings *settings ) { + int rc; + + initscr(); + start_color(); + init_pair ( CPAIR_NORMAL, COLOR_WHITE, COLOR_BLUE ); + init_pair ( CPAIR_SELECT, COLOR_WHITE, COLOR_RED ); + init_pair ( CPAIR_EDIT, COLOR_BLACK, COLOR_CYAN ); + init_pair ( CPAIR_ALERT, COLOR_WHITE, COLOR_RED ); + color_set ( CPAIR_NORMAL, NULL ); + erase(); + + rc = main_loop ( settings ); + + endwin(); + + return rc; +} diff --git a/contrib/syslinux-4.02/gpxe/src/hci/wireless_errors.c b/contrib/syslinux-4.02/gpxe/src/hci/wireless_errors.c new file mode 100644 index 0000000..46006f9 --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/hci/wireless_errors.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * 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_LICENCE ( GPL2_OR_LATER ); + +#include <errno.h> +#include <gpxe/errortab.h> + +/* Record errors as though they come from the 802.11 stack */ +#undef ERRFILE +#define ERRFILE ERRFILE_net80211 + +/** All 802.11 errors + * + * These follow the 802.11 standard as much as is feasible, but most + * have been abbreviated to fit the 50-character limit imposed by + * strerror. + */ +struct errortab wireless_errors[] __errortab = { + /* gPXE 802.11 stack errors */ + { EINVAL | EUNIQ_01, "Packet too short" }, + { EINVAL | EUNIQ_02, "Packet 802.11 version not supported" }, + { EINVAL | EUNIQ_03, "Packet not a data packet" }, + { EINVAL | EUNIQ_04, "Packet not from an Access Point" }, + { EINVAL | EUNIQ_05, "Packet has invalid LLC header" }, + { EINVAL | EUNIQ_06, "Packet decryption error", }, + { EINVAL | EUNIQ_07, "Invalid active scan requested" }, + + /* 802.11 status codes (IEEE Std 802.11-2007, Table 7-23) */ + /* Maximum error length: 50 chars | */ + { ECONNREFUSED | EUNIQ_01, "Unspecified failure" }, + { ECONNREFUSED | EUNIQ_0A, "Cannot support all requested capabilities" }, + { ECONNREFUSED | EUNIQ_0B, "Reassociation denied due to lack of association" }, + { ECONNREFUSED | EUNIQ_0C, "Association denied for another reason" }, + { ECONNREFUSED | EUNIQ_0D, "Authentication algorithm unsupported" }, + { ECONNREFUSED | EUNIQ_0E, "Authentication sequence number unexpected" }, + { ECONNREFUSED | EUNIQ_0F, "Authentication rejected due to challenge failure" }, + { ECONNREFUSED | EUNIQ_10, "Authentication rejected due to timeout" }, + { ECONNREFUSED | EUNIQ_11, "Association denied because AP is out of resources" }, + { ECONNREFUSED | EUNIQ_12, "Association denied; basic rate support required" }, + { ECONNREFUSED | EUNIQ_13, "Association denied; short preamble support req'd" }, + { ECONNREFUSED | EUNIQ_14, "Association denied; PBCC modulation support req'd" }, + { ECONNREFUSED | EUNIQ_15, "Association denied; Channel Agility support req'd" }, + { ECONNREFUSED | EUNIQ_16, "Association denied; Spectrum Management required" }, + { ECONNREFUSED | EUNIQ_17, "Association denied; Power Capability unacceptable" }, + { ECONNREFUSED | EUNIQ_18, "Association denied; Supported Channels unacceptable" }, + { ECONNREFUSED | EUNIQ_19, "Association denied; Short Slot Tume support req'd" }, + { ECONNREFUSED | EUNIQ_1A, "Association denied; DSSS-OFDM support required" }, + { EHOSTUNREACH, "Unspecified, QoS-related failure" }, + { EHOSTUNREACH | EUNIQ_01, "Association denied; QoS AP out of QoS resources" }, + { EHOSTUNREACH | EUNIQ_02, "Association denied due to excessively poor link" }, + { EHOSTUNREACH | EUNIQ_03, "Association denied; QoS support required" }, + { EHOSTUNREACH | EUNIQ_05, "The request has been declined" }, + { EHOSTUNREACH | EUNIQ_06, "Request unsuccessful due to invalid parameters" }, + { EHOSTUNREACH | EUNIQ_07, "TS not created due to bad specification" }, + { EHOSTUNREACH | EUNIQ_08, "Invalid information element" }, + { EHOSTUNREACH | EUNIQ_09, "Invalid group cipher" }, + { EHOSTUNREACH | EUNIQ_0A, "Invalid pairwise cipher" }, + { EHOSTUNREACH | EUNIQ_0B, "Invalid AKMP" }, + { EHOSTUNREACH | EUNIQ_0C, "Unsupported RSN information element version" }, + { EHOSTUNREACH | EUNIQ_0D, "Invalid RSN information element capabilities" }, + { EHOSTUNREACH | EUNIQ_0E, "Cipher suite rejected because of security policy" }, + { EHOSTUNREACH | EUNIQ_0F, "TS not created due to insufficient delay" }, + { EHOSTUNREACH | EUNIQ_10, "Direct link is not allowed in the BSS by policy" }, + { EHOSTUNREACH | EUNIQ_11, "The Destination STA is not present within the BSS" }, + { EHOSTUNREACH | EUNIQ_12, "The Destination STA is not a QoS STA" }, + { EHOSTUNREACH | EUNIQ_13, "Association denied; Listen Interval is too large" }, + + /* 802.11 reason codes (IEEE Std 802.11-2007, Table 7-22) */ + /* Maximum error length: 50 chars | */ + { ECONNRESET | EUNIQ_01, "Unspecified reason" }, + { ECONNRESET | EUNIQ_02, "Previous authentication no longer valid" }, + { ECONNRESET | EUNIQ_03, "Deauthenticated due to leaving network" }, + { ECONNRESET | EUNIQ_04, "Disassociated due to inactivity" }, + { ECONNRESET | EUNIQ_05, "Disassociated because AP is out of resources" }, + { ECONNRESET | EUNIQ_06, "Class 2 frame received from nonauthenticated STA" }, + { ECONNRESET | EUNIQ_07, "Class 3 frame received from nonassociated STA" }, + { ECONNRESET | EUNIQ_08, "Disassociated due to roaming" }, + { ECONNRESET | EUNIQ_09, "STA requesting (re)association not authenticated" }, + { ECONNRESET | EUNIQ_0A, "Disassociated; Power Capability unacceptable" }, + { ECONNRESET | EUNIQ_0B, "Disassociated; Supported Channels unacceptable" }, + { ECONNRESET | EUNIQ_0D, "Invalid information element" }, + { ECONNRESET | EUNIQ_0E, "Message integrity code (MIC) failure" }, + { ECONNRESET | EUNIQ_0F, "4-Way Handshake timeout" }, + { ECONNRESET | EUNIQ_10, "Group Key Handshake timeout" }, + { ECONNRESET | EUNIQ_11, "4-Way Handshake information element changed unduly" }, + { ECONNRESET | EUNIQ_12, "Invalid group cipher" }, + { ECONNRESET | EUNIQ_13, "Invalid pairwise cipher" }, + { ECONNRESET | EUNIQ_14, "Invalid AKMP" }, + { ECONNRESET | EUNIQ_15, "Unsupported RSN information element version" }, + { ECONNRESET | EUNIQ_16, "Invalid RSN information element capabilities" }, + { ECONNRESET | EUNIQ_17, "IEEE 802.1X authentication failed" }, + { ECONNRESET | EUNIQ_18, "Cipher suite rejected because of security policy" }, + { ENETRESET, "Disassociated for unspecified, QoS-related reason" }, + { ENETRESET | EUNIQ_01, "Disassociated; QoS AP is out of QoS resources" }, + { ENETRESET | EUNIQ_02, "Disassociated due to excessively poor link" }, + { ENETRESET | EUNIQ_03, "Disassociated due to TXOP limit violation" }, + { ENETRESET | EUNIQ_04, "Requested; STA is leaving the BSS (or resetting)" }, + { ENETRESET | EUNIQ_05, "Requested; does not want to use the mechanism" }, + { ENETRESET | EUNIQ_06, "Requested; setup is required" }, + { ENETRESET | EUNIQ_07, "Requested from peer STA due to timeout" }, + { ENETRESET | EUNIQ_0D, "Peer STA does not support requested cipher suite" }, +}; |