aboutsummaryrefslogtreecommitdiffstats
path: root/com32/elflink
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-03-20 17:14:21 +0000
committerMatt Fleming <matt.fleming@intel.com>2013-03-22 13:57:44 +0000
commit37d43cf9dd5dd2d2cef1e86aa651097473fd0b48 (patch)
tree07a7df546f178c4e1576f4cbcc0bb4db3a8e18b4 /com32/elflink
parentbf20364b582c383b4927f898de213b1cc0981a80 (diff)
parenta107cb3b6fa219cf5f65bef366c9b00b108e9a3a (diff)
downloadsyslinux-37d43cf9dd5dd2d2cef1e86aa651097473fd0b48.tar.gz
syslinux-37d43cf9dd5dd2d2cef1e86aa651097473fd0b48.tar.xz
syslinux-37d43cf9dd5dd2d2cef1e86aa651097473fd0b48.zip
Merge tag 'syslinux-5.10-pre2' into for-hpa/elflink/firmware
syslinux-5.10-pre2 Conflicts: NEWS com32/include/netinet/in.h com32/include/sys/cpu.h com32/lib/Makefile core/Makefile core/fs/diskio.c core/fs/pxe/pxe.h core/init.c core/mem/free.c core/mem/malloc.c mk/devel.mk version
Diffstat (limited to 'com32/elflink')
-rw-r--r--com32/elflink/ldlinux/chainboot.c3
-rw-r--r--com32/elflink/ldlinux/execute.c41
-rw-r--r--com32/elflink/ldlinux/kernel.c17
-rw-r--r--com32/elflink/ldlinux/ldlinux.c36
-rw-r--r--com32/elflink/ldlinux/readconfig.c67
5 files changed, 124 insertions, 40 deletions
diff --git a/com32/elflink/ldlinux/chainboot.c b/com32/elflink/ldlinux/chainboot.c
index ff19c530..27d4618c 100644
--- a/com32/elflink/ldlinux/chainboot.c
+++ b/com32/elflink/ldlinux/chainboot.c
@@ -15,6 +15,7 @@
* is BIOS-specific.
*/
+#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -53,7 +54,7 @@ void chainboot_file(const char *file, uint32_t type)
if (!buf)
goto bail;
- rv = open_file(file, &fd);
+ rv = open_file(file, O_RDONLY, &fd);
if (rv == -1)
goto bail;
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 5c53b995..bf0bd8ce 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -46,16 +46,21 @@ const struct image_types image_boot_types[] = {
extern int create_args_and_load(char *);
-__export void execute(const char *cmdline, uint32_t type)
+__export void execute(const char *cmdline, uint32_t type, bool sysappend)
{
const char *kernel, *args;
const char *p;
com32sys_t ireg;
- char *q;
+ char *q, ch;
memset(&ireg, 0, sizeof ireg);
- q = malloc(strlen(cmdline) + 2);
+ if (strlen(cmdline) >= MAX_CMDLINE_LEN) {
+ printf("cmdline too long\n");
+ return;
+ }
+
+ q = malloc(MAX_CMDLINE_LEN);
if (!q) {
printf("%s(): Fail to malloc a buffer to exec %s\n",
__func__, cmdline);
@@ -72,7 +77,17 @@ __export void execute(const char *cmdline, uint32_t type)
while (*p && my_isspace(*p))
p++;
- strcpy(q, p);
+ do {
+ *q++ = ch = *p++;
+ } while (ch);
+
+ if (sysappend) {
+ /* If we've seen some args, insert a space */
+ if (--q != args)
+ *q++ = ' ';
+
+ do_sysappend(q);
+ }
dprintf("kernel is %s, args = %s type = %d \n", kernel, args, type);
@@ -86,13 +101,14 @@ __export void execute(const char *cmdline, uint32_t type)
* filename extension if COM32 and
* retry.
*/
+ p = args;
if (t->type == IMAGE_TYPE_COM32) {
p = apply_extension(p, ".c32");
if (!p)
return;
}
- execute(p, t->type);
+ execute(p, t->type, sysappend);
return;
}
}
@@ -122,17 +138,23 @@ __export void execute(const char *cmdline, uint32_t type)
ldlinux_enter_command();
} else if (type == IMAGE_TYPE_CONFIG) {
- char *argv[] = { "ldlinux.c32", NULL };
+ char *argv[] = { "ldlinux.c32", NULL, NULL };
+ char *config;
int rv;
/* kernel contains the config file name */
- realpath(ConfigName, kernel, FILENAME_MAX);
+ config = malloc(FILENAME_MAX);
+ if (!config)
+ goto out;
+
+ realpath(config, kernel, FILENAME_MAX);
/* If we got anything on the command line, do a chdir */
if (*args)
mangle_name(config_cwd, args);
- rv = start_ldlinux(argv);
+ argv[1] = config;
+ rv = start_ldlinux(2, argv);
printf("Failed to exec ldlinux.c32: %s\n", strerror(rv));
} else if (type == IMAGE_TYPE_LOCALBOOT) {
local_boot(strtoul(kernel, NULL, 0));
@@ -142,9 +164,10 @@ __export void execute(const char *cmdline, uint32_t type)
} else {
/* Need add one item for kernel load, as we don't use
* the assembly runkernel.inc any more */
- new_linux_kernel((char *)kernel, (char *)cmdline);
+ new_linux_kernel((char *)kernel, (char *)args);
}
+out:
free((void *)kernel);
/* If this returns, something went bad; return to menu */
diff --git a/com32/elflink/ldlinux/kernel.c b/com32/elflink/ldlinux/kernel.c
index 920246fc..f3ba37fa 100644
--- a/com32/elflink/ldlinux/kernel.c
+++ b/com32/elflink/ldlinux/kernel.c
@@ -35,14 +35,10 @@ int new_linux_kernel(char *okernel, char *ocmdline)
else if (append)
args = append;
- cmdline_len = strlen(kernel_name);
- if (args) {
- /* +1 for the space (' ') between kernel and args */
- cmdline_len += strlen(args) + 1;
- }
-
- /* +1 for NUL termination */
- cmdline_len++;
+ cmdline_len = strlen("BOOT_IMAGE=") + strlen(kernel_name);
+ cmdline_len += 1; /* space between BOOT_IMAGE and args */
+ cmdline_len += strlen(args);
+ cmdline_len += 1; /* NUL-termination */
cmdline = malloc(cmdline_len);
if (!cmdline) {
@@ -50,10 +46,7 @@ int new_linux_kernel(char *okernel, char *ocmdline)
return 1;
}
- if (args)
- snprintf(cmdline, cmdline_len, "%s %s", kernel_name, args);
- else
- snprintf(cmdline, cmdline_len, "%s", kernel_name);
+ sprintf(cmdline, "BOOT_IMAGE=%s %s", kernel_name, args);
/* "keeppxe" handling */
#if IS_PXELINUX
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index a8b1b386..76d117c7 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -154,9 +154,29 @@ __export void load_kernel(const char *command_line)
/* Virtual kernel? */
me = find_label(kernel);
if (me) {
- type = parse_image_type(me->cmdline);
+ const char *args;
+ char *cmd;
+ size_t len = strlen(me->cmdline) + 1;
- execute(me->cmdline, type);
+ /* Find the end of the command */
+ args = find_command(kernel);
+ while(*args && my_isspace(*args))
+ args++;
+
+ if (strlen(args))
+ len += strlen(args) + 1; /* +1 for space (' ') */
+
+ cmd = malloc(len);
+ if (!cmd)
+ goto bad_kernel;
+
+ if (strlen(args))
+ snprintf(cmd, len, "%s %s", me->cmdline, args);
+ else
+ strncpy(cmd, me->cmdline, len);
+
+ type = parse_image_type(cmd);
+ execute(cmd, type, false);
/* We shouldn't return */
goto bad_kernel;
}
@@ -193,7 +213,7 @@ __export void load_kernel(const char *command_line)
}
}
- execute(kernel, type);
+ execute(kernel, type, true);
free((void *)kernel);
bad_implicit:
@@ -210,7 +230,7 @@ bad_kernel:
rsprintf(&cmdline, "%s %s", onerror, default_cmd);
type = parse_image_type(cmdline);
- execute(cmdline, type);
+ execute(cmdline, type, true);
}
}
@@ -277,19 +297,15 @@ void ldlinux_console_init(void)
openconsole(&dev_stdcon_r, &dev_ansiserial_w);
}
-__export int main(int argc __unused, char **argv __unused)
+__export int main(int argc __unused, char **argv)
{
const void *adv;
const char *cmdline;
size_t count = 0;
- char *config_argv[2] = { NULL, NULL };
ldlinux_console_init();
- if (ConfigName[0])
- config_argv[0] = ConfigName;
-
- parse_configs(config_argv);
+ parse_configs(&argv[1]);
__syslinux_set_serial_console_info();
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index a2421e95..9d50c2f3 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -29,6 +29,7 @@
#include <bios.h>
#include <core.h>
#include <fs.h>
+#include <syslinux/pxe_api.h>
#include "menu.h"
#include "config.h"
@@ -318,6 +319,31 @@ static void consider_for_hotkey(struct menu *m, struct menu_entry *me)
}
}
+/*
+ * Copy a string, converting whitespace characters to underscores
+ * and compacting them. Return a pointer to the final null.
+ */
+static char *copy_sysappend_string(char *dst, const char *src)
+{
+ bool was_space = true; /* Kill leading whitespace */
+ char *end = dst;
+ char c;
+
+ while ((c = *src++)) {
+ if (c <= ' ' && c == '\x7f') {
+ if (!was_space)
+ *dst++ = '_';
+ was_space = true;
+ } else {
+ *dst++ = c;
+ end = dst;
+ was_space = false;
+ }
+ }
+ *end = '\0';
+ return end;
+}
+
static void record(struct menu *m, struct labeldata *ld, const char *append)
{
int i;
@@ -381,8 +407,11 @@ static void record(struct menu *m, struct labeldata *ld, const char *append)
if (ld->ipappend) {
ipappend = syslinux_ipappend_strings();
for (i = 0; i < ipappend->count; i++) {
- if ((ld->ipappend & (1U << i)) && ipappend->ptr[i])
- ipp += sprintf(ipp, " %s", ipappend->ptr[i]);
+ if ((ld->ipappend & (1U << i)) &&
+ ipappend->ptr[i] && ipappend->ptr[i][0]) {
+ *ipp++ = ' ';
+ ipp = copy_sysappend_string(ipp, ipappend->ptr[i]);
+ }
}
}
@@ -444,6 +473,9 @@ void print_labels(const char *prefix, size_t len)
printf("\n");
for (me = all_entries; me; me = me->next ) {
+ if (!me->label)
+ continue;
+
if (!strncmp(prefix, me->label, len))
printf(" %s", me->label);
}
@@ -605,8 +637,6 @@ uint32_t parse_argb(char **p)
*/
//static const char *append = NULL;
extern const char *append;
-//static unsigned int ipappend = 0;
-__export unsigned int ipappend = 0;
extern uint16_t PXERetry;
static struct labeldata ld;
@@ -1074,7 +1104,7 @@ do_include:
ld.initrd = NULL;
ld.menulabel = NULL;
ld.helptext = NULL;
- ld.ipappend = ipappend;
+ ld.ipappend = SysAppends;
ld.menudefault = ld.menuhide = ld.menuseparator =
ld.menudisabled = ld.menuindent = 0;
} else if ((ep = is_kernel_type(p, &type))) {
@@ -1093,11 +1123,13 @@ do_include:
ontimeoutlen = strlen(ontimeout);
} else if (looking_at(p, "allowoptions")) {
allowoptions = !!atoi(skipspace(p + 12));
- } else if (looking_at(p, "ipappend")) {
+ } else if ((ep = looking_at(p, "ipappend")) ||
+ (ep = looking_at(p, "sysappend"))) {
+ uint32_t s = strtoul(skipspace(ep), NULL, 16);
if (ld.label)
- ld.ipappend = atoi(skipspace(p + 8));
+ ld.ipappend = s;
else
- ipappend = atoi(skipspace(p + 8));
+ SysAppends = s;
} else if (looking_at(p, "default")) {
/* default could be a kernel image or another label */
refstr_put(globaldefault);
@@ -1333,6 +1365,16 @@ do_include:
PATH = _p;
} else
printf("Failed to realloc PATH\n");
+ } else if (looking_at(p, "sendcookies")) {
+ const union syslinux_derivative_info *sdi;
+
+ p += strlen("sendcookies");
+ sdi = syslinux_derivative_info();
+
+ if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
+ SendCookies = strtoul(skipspace(p), NULL, 10);
+ http_bake_cookies();
+ }
}
}
}
@@ -1360,6 +1402,15 @@ static int parse_one_config(const char *filename)
f = fdopen(fd, mode);
parse_config_file(f);
+ /*
+ * Update ConfigName so that syslinux_config_file() returns
+ * the filename we just opened. filesystem-specific
+ * open_config() implementations are expected to update
+ * ConfigName themselves.
+ */
+ if (filename)
+ strcpy(ConfigName, filename);
+
return 0;
}