[syslinux] NEW: COM32 module to alias (Revised)

Gene Cumm gene.cumm at gmail.com
Mon Oct 27 16:40:57 PDT 2008


From: Gene Cumm <gene.cumm at gmail.com>

alias.c: A simple COM32 module that allows the creation of an alias
within the config for SYSLINUX and variants.

Signed-off-by: Gene Cumm <gene.cumm at gmail.com>

---

Revised based on previous discussion on this list <syslinux at zytor.com>
to change the command line string size and account for the possibility
of overflowing the string.  Overflowing within SYSLINUX would probably
only occur if the command line string size was increased in a later
version without recompiling this module to accommodate the change.

I still classify this as BETA software, mostly for the fact that to my
knowledge, I'm the only one that has tested this.  I can not forsee
any other potential issues in the code at this time.  I would think
that this file, if included into SYSLINUX, would be most appropriately
placed in either com32/samples or com32/modules, depending on where H.
Peter Anvin feels it is most appropriate.

If, for example, you had two labels that only differed by the length
of the label (a short name) or additional APPENDd parameters, this
would reduce the amount of copies of the same configuration.

LABEL boot1
KERNEL kernel
APPEND initrd=initrd.img

LABEL boot2
KERNEL kernel
APPEND initrd=initrd.img extraParamForBoot2

could be shortened to

LABEL boot1
KERNEL kernel
APPEND initrd=initrd.img

LABEL boot2
KERNEL alias.c32
APPEND boot1 extraParamForBoot2

I created this as I've got several instances of both short names and
extra APPENDd parameters in a config file I use.  The only thing that
would be better (if this benefits others) would be an ALIAS option in
the config file.

alias.c:
/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2008 Gene Cumm - All Rights Reserved
 *
 *   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, Inc., 53 Temple Place Ste 330,
 *   Boston MA 02111-1307, USA; either version 2 of the License, or
 *   (at your option) any later version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

/*
 * alias.c
 *
 * Alias COM32 application;  Call as a KERNEL with a boot line command as the
 * APPEND line.
 */

/*
 * History
 * b003	Work on resolving a potential overflow issue with building the
 *	command string to pass to syslinux_run_command()
 * 	Reformatted {} in more visual style.
 * 	Use MAX_CMDLINE_LEN or COMMAND_LINE_SIZE (in that order) if available
 * b002	Alter the concatenation of the command line arguments to use memcpy
 * b001	Initial version
 */

#include <stdio.h>
#include <stdlib.h>
// #include <stdbool.h>
#include <string.h>
#include <limits.h>

#ifdef __COM32__		/* Allow targetting Linux, etc to test */
#include <syslinux/boot.h>	/* syslinux_run_command() */
#endif	/* __COM32__ */

#ifdef __linux__		/* For COMMAND_LINE_SIZE */
#include <asm/setup.h>
#endif	/* __linux__ */

// Possible referenced values for command line length:
//	MAX_CMDLINE_LEN (com32/menu/menu.h)
//	LINE_MAX or _POSIX2_LINE_MAX	<limits.h> on *nix systems;
//		Seem more appropriate for a shell command line
//	COMMAND_LINE_SIZE <asm/setup.h> on a Linux system
#ifdef MAX_CMDLINE_LEN
#define ALIAS_CMD_SZ	MAX_CMDLINE_LEN
#else
#ifdef COMMAND_LINE_SIZE
#define ALIAS_CMD_SZ	COMMAND_LINE_SIZE
#else
#define ALIAS_CMD_SZ	2048
#endif	/* COMMAND_LINE_SIZE */
#endif	/* MAX_CMDLINE_LEN */

// #define DO_DEBUG 1	/* Uncomment this for additional output

#define APP_LONGNAME	"Alias COM32"
#define APP_NAME	"alias"
#define APP_YEAR	"2008"
#define APP_AUTHOR	"Gene Cumm"
#define APP_VER		"beta-b003"

int main(int argc, char *argv[])
{
	char cmdstr[ALIAS_CMD_SZ];	// Command string to execute
	int curpos;	// Current position in cmdstr; Use memcpy rather than strcat
	int arglen;	// length of current argument string
	int i;

	// Initialization
	curpos = 0;
	cmdstr[0] = 0;
#ifdef DO_DEBUG
	printf("\n%d\n\n", ALIAS_CMD_SZ);
#endif	/* DO_DEBUG */
	for(i=1; i<argc; i++)
	{
		arglen = strlen(argv[i]);
		// Theoretically, this should never be met in SYSLINUX
		if ((curpos + arglen) > (ALIAS_CMD_SZ - 1))
			arglen = (ALIAS_CMD_SZ - 1) - curpos;
		memcpy(cmdstr + curpos, argv[i], arglen);
		curpos += arglen;
		if (curpos >= (ALIAS_CMD_SZ - 1))
		{	//Hopefully, curpos should not be greater than (ALIAS_CMD_SZ - 1)
			// Still need a '\0' at the last character
			cmdstr[(ALIAS_CMD_SZ - 1)] = 0;
			break;	// Escape out of the for() loop;  We can no longer process
anything more
		}else
		{
			cmdstr[curpos] = ' ';
			curpos += 1;
			cmdstr[curpos] = 0;
		}
	}
	curpos -= 1;
	if(cmdstr[curpos] == ' ')
		// If there's a ' ' at the end, remove it.  This is normal
		// unless the maximum length is met/exceeded.
		cmdstr[curpos] = 0;
#ifdef DO_DEBUG
	printf("Parsed arg list\n");
#endif	/* DO_DEBUG */
	printf("--alias: '%s'\n", cmdstr);
#ifdef __COM32__
	syslinux_run_command(cmdstr);
#endif	/* __COM32__ */

	return 0;
}




More information about the Syslinux mailing list