[syslinux] Syslinux search for config file

Matt Fleming matt at console-pimps.org
Thu Nov 15 06:21:48 PST 2012


On Mon, 2012-11-12 at 16:03 +0100, Gert Hulselmans wrote:
> Hi Mat,
> 
> 
> 
> Why is the function called dir_fat_mangle? The Syslinux Windows
> installer can install on FAT12/16/32 and NTFS.
> 
> Something like dir_backslash_mangle might be a better name.

Yes, that does seem like a better name.

> In win/syslinux.c the part of the code that moves LDLINUX.SYS needs a
> small cleanup too,
> now that opt.directory always contains a forward slash:
> 
>     /* Move the file to the desired location */
>     if (opt.directory) {
> 	char new_ldlinux_name[strlen(opt.directory) + 16];
> 	char *cp = new_ldlinux_name + 3;
> 	const char *sd;
> 	int slash = 1;
> 
> 	new_ldlinux_name[0] = opt.device[0];
> 	new_ldlinux_name[1] = ':';
> 	new_ldlinux_name[2] = '\\';
> 
> 	for (sd = opt.directory; *sd; sd++) {
> 	    char c = *sd;
> 
> -	    if (c == '/' || c == '\\') {
> +	    if (c == '/') {
> 		if (slash)
> 		    continue;
> 		c = '\\';
> 		slash = 1;
> 	    } else {
> 		slash = 0;
> 	    }
> 
> 	    *cp++ = c;
> 	}

Right.

> This code is also quite similar to the code in dir_fat_mangle.
> 
> I don't know if it is worth the effort to make dir_fat_mangle more
> general so it can generate
> a path with '/' or '\' slashes depending on the second argument:

I don't think so, it's only a handful of lines, and in the case below
the 'slash' variable is used after the mangling.

> if (mode == MODE_SYSLINUX_DOSWIN) {
>     opt.directory = dir_fat_mangle(optarg, 0);
>     opt.backslashesdirectory = dir_fat_mangle(optarg, 1);
> 
> 
> win/syslinux.c needs the slash variable later for:
> 
> 	/* Skip if subdirectory == root */
> 	if (cp > new_ldlinux_name + 3) {
> 	    if (!slash)
> 		*cp++ = '\\';

This code has all been moved in 5.00 into a function called move_file()
so we don't need opt.backslashesdirectory.

And I just noticed that mtools/syslinux seems to expect users might
include backslashes in the -d option also, so I've removed the
conditional for MODE_SYSLINUX_DOSWIN. Below is the updated version. Is
anyone able to test it? If not I'll probably just apply it to the next
5.00 prerelease.

---

>From fbe2bba4a336393735cab95959b69f10ab62d2d7 Mon Sep 17 00:00:00 2001
From: Matt Fleming <matt.fleming at intel.com>
Date: Thu, 8 Nov 2012 17:51:33 +0000
Subject: [PATCH] libinstaller: Mangle win pathnames into Syslinux pathnames

The Syslinux code deals exclusively with '/' as path component
separators. If a pathname containing '\' is used as the directory
argument during installation, e.g.

    syslinux.exe -d \slax\boot F:

the pathname is inserted into the ADV structure verbatim.
Unfortunately, the config code doesn't understand pathnames with
backslashes and therefore won't search in the installation directory
for the config file.

Mangle the pathname in parse_options() so that all the installers know
they're dealing with a '/' separated directory argument. If code
requires a win-style pathname, it will have to unmangle it explicitly,
e.g. move_file() in win/syslinux.c.

Cc: Gert Hulselmans <hulselmansgert at gmail.com>
Cc: Tomas M <tomas at slax.org>
Signed-off-by: Matt Fleming <matt.fleming at intel.com>
---
 dos/syslinux.c          |  2 +-
 libinstaller/syslxopt.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 mtools/syslinux.c       |  2 +-
 win/syslinux.c          |  2 +-
 4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/dos/syslinux.c b/dos/syslinux.c
index eb8bace..996050b 100644
--- a/dos/syslinux.c
+++ b/dos/syslinux.c
@@ -597,7 +597,7 @@ static void move_file(int dev_fd, char *pathname, char *filename)
     for (sd = opt.directory; *sd; sd++) {
 	char c = *sd;
 
-	if (c == '/' || c == '\\') {
+	if (c == '/') {
 	    if (slash)
 		continue;
 	    c = '\\';
diff --git a/libinstaller/syslxopt.c b/libinstaller/syslxopt.c
index b739752..d742d92 100644
--- a/libinstaller/syslxopt.c
+++ b/libinstaller/syslxopt.c
@@ -132,6 +132,41 @@ void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode)
     exit(rv);
 }
 
+/*
+ * Convert backslashes '\\' in a pathname into forward slashes '/'.
+ */
+static char *dir_backslash_mangle(const char *dir)
+{
+    const char *sd;
+    char *s, *cp;
+    size_t size;
+    int slash = 1;
+
+    size = strlen(dir) + 1;
+    s = malloc(size);
+    if (!s)
+	return s;
+
+    memset(s, 0, size);
+
+    for (sd = dir, cp = s; *sd; sd++) {
+	char c = *sd;
+
+	if (c == '/' || c == '\\') {
+	    if (slash)
+		continue;
+	    c = '/';
+	    slash = 1;
+	} else {
+	    slash = 0;
+	}
+
+	*cp++ = c;
+    }
+
+    return s;
+}
+
 void parse_options(int argc, char *argv[], enum syslinux_mode mode)
 {
     int o;
@@ -198,7 +233,11 @@ void parse_options(int argc, char *argv[], enum syslinux_mode mode)
 	    opt.set_once = "";
 	    break;
 	case 'd':
-	    opt.directory = optarg;
+	    opt.directory = dir_backslash_mangle(optarg);
+	    if (!opt.directory) {
+		fprintf(stderr, "Failed to mangle directory argument\n");
+		exit(EX_USAGE);
+	    }
 	    break;
 	case OPT_RESET_ADV:
 	    opt.reset_adv = 1;
diff --git a/mtools/syslinux.c b/mtools/syslinux.c
index f43b5a5..9c169e7 100755
--- a/mtools/syslinux.c
+++ b/mtools/syslinux.c
@@ -135,7 +135,7 @@ static int move_file(char *filename)
 
     cp += sprintf(cp, "'s:/");
     for (sd = opt.directory; *sd; sd++) {
-	if (*sd == '/' || *sd == '\\') {
+	if (*sd == '/') {
 	    if (slash)
 		continue;	/* Remove duplicated slashes */
 	    slash = 1;
diff --git a/win/syslinux.c b/win/syslinux.c
index c291f00..f548e0c 100644
--- a/win/syslinux.c
+++ b/win/syslinux.c
@@ -250,7 +250,7 @@ static void move_file(char *pathname, char *filename)
     for (sd = opt.directory; *sd; sd++) {
 	char c = *sd;
 
-	if (c == '/' || c == '\\') {
+	if (c == '/') {
 	    if (slash)
 		continue;
 	    c = '\\';
-- 
1.7.11.7



-- 
Matt Fleming, Intel Open Source Technology Center




More information about the Syslinux mailing list