diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-06-13 11:46:40 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-06-13 11:51:03 +0100 |
commit | 19455794d144c2c38f483890e0d384bc43b5fd63 (patch) | |
tree | a6929fba7955d1ac5455aca1328d0963d06c84e9 /com32/lib/sys | |
parent | ec1f4593622bef1b0bf9fdc95f55c520751240bd (diff) | |
download | syslinux-19455794d144c2c38f483890e0d384bc43b5fd63.tar.gz syslinux-19455794d144c2c38f483890e0d384bc43b5fd63.tar.xz syslinux-19455794d144c2c38f483890e0d384bc43b5fd63.zip |
PATH: use a linked list internallysyslinux-5.11-pre1
In retrospect, choosing the colon character as the entry separator for
the PATH directive was not a smart move, as that character is also used
in TFTP-style paths. This conflict manifests as PXELINUX being unable to
find and load files.
An example dnsmasq log looks like,
dnsmasq-tftp: sent /arch/boot/syslinux/lpxelinux.0 to 192.168.0.90
dnsmasq-tftp: file /arch/ldlinux.c32 not found
dnsmasq-tftp: file /arch//ldlinux.c32 not found
dnsmasq-tftp: file /arch//boot/isolinux/ldlinux.c32 not found
dnsmasq-tftp: file /arch//isolinux/ldlinux.c32 not found
dnsmasq-tftp: file /arch//boot/syslinuxldlinux.c32 not found
dnsmasq-tftp: sent /arch//boot/syslinux/ldlinux.c32 to 192.168.0.90
dnsmasq-tftp: error 0 No error, file close received from 192.168.0.90
dnsmasq-tftp: failed sending /arch//boot/syslinux/ldlinux.c32 to 192.168.0.90
dnsmasq-tftp: sent /arch/boot/syslinux/archiso.cfg to 192.168.0.90
dnsmasq-tftp: sent /arch/boot/syslinux/whichsys.c32 to 192.168.0.90
dnsmasq-tftp: file /arch/libcom32.c32 not found
dnsmasq-tftp: file /arch//libcom32.c32 not found
dnsmasq-tftp: file /arch/libcom32.c32 not found
dnsmasq-tftp: file /arch//arch//boot/syslinux/libcom32.c32 not found
The last line of the log is the indication that there's a problem.
Internally, Syslinux adds the location of ldlinux.c32 to PATH by
querying the current working directory once ldlinux.c32 is successfully
loaded. Under PXELINUX that means the initial PATH string will be,
"::/arch/boot/syslinux/"
The PATH parsing code doesn't know how to correctly parse the "::"
string and hence, the file is searched for relative to the 210 dhcp
option directory - /arch/.
Implement PATH with a linked list which *greatly* simplifies the path
code, and means we no longer have to parse strings backwards and
forwards.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'com32/lib/sys')
-rw-r--r-- | com32/lib/sys/module/common.c | 36 |
1 files changed, 12 insertions, 24 deletions
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c index 8547036b..b763704e 100644 --- a/com32/lib/sys/module/common.c +++ b/com32/lib/sys/module/common.c @@ -59,40 +59,28 @@ void print_elf_symbols(struct elf_module *module) { FILE *findpath(char *name) { + struct path_entry *entry; char path[FILENAME_MAX]; FILE *f; - char *p, *n; - int i; f = fopen(name, "rb"); /* for full path */ if (f) return f; - p = PATH; -again: - i = 0; - while (*p && *p != ':' && i < FILENAME_MAX - 1) { - path[i++] = *p++; - } - - if (*p == ':') - p++; + list_for_each_entry(entry, &PATH, list) { + bool slash = false; - /* Ensure we have a '/' separator */ - if (path[i] != '/' && i < FILENAME_MAX - 1) - path[i++] = '/'; + /* Ensure we have a '/' separator */ + if (entry->str[strlen(entry->str) - 1] != '/') + slash = true; - n = name; - while (*n && i < FILENAME_MAX - 1) - path[i++] = *n++; - path[i] = '\0'; + snprintf(path, sizeof(path), "%s%s%s", + entry->str, slash ? "/" : "", name); - f = fopen(path, "rb"); - if (f) - return f; - - if (p >= PATH && p < PATH + strlen(PATH)) - goto again; + f = fopen(path, "rb"); + if (f) + return f; + } return NULL; } |