diff options
Diffstat (limited to 'dos')
-rw-r--r-- | dos/syslinux.c | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/dos/syslinux.c b/dos/syslinux.c index f3b08367..e4066ca5 100644 --- a/dos/syslinux.c +++ b/dos/syslinux.c @@ -36,7 +36,7 @@ uint16_t dos_version; void __attribute__((noreturn)) usage(void) { - puts("Usage: syslinux [-sfma] <drive>: [bootsecfile]\n"); + puts("Usage: syslinux [-sfma][-d directory] <drive>: [bootsecfile]\n"); exit(1); } @@ -51,6 +51,13 @@ void __attribute__((noreturn)) die(const char *msg) exit(1); } +void warning(const char *msg) +{ + puts("syslinux: warning: "); + puts(msg); + putchar('\n'); +} + /* * read/write wrapper functions */ @@ -63,7 +70,7 @@ int creat(const char *filename, int mode) rv = 0x3C00; asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) + : "=bcdm" (err), "+a" (rv) : "c" (mode), "d" (filename)); if ( err ) { dprintf("rv = %d\n", rv); @@ -87,6 +94,26 @@ void close(int fd) and we really don't care... */ } +int rename(const char *oldname, const char *newname) +{ + uint16_t rv = 0x5600; /* Also support 43FFh? */ + uint8_t err; + + dprintf("rename(\"%s\", \"%s\")\n", oldname, newname); + + asm volatile("int $0x21 ; setc %0" + : "=bcdm" (err), "+a" (rv) + : "d" (oldname), "D" (newname)); + + if ( err ) { + dprintf("rv = %d\n", rv); + warning("cannot move ldlinux.sys"); + return rv; + } + + return 0; +} + ssize_t write_file(int fd, const void *buf, size_t count) { uint16_t rv; @@ -449,7 +476,7 @@ int main(int argc, char *argv[]) { static unsigned char sectbuf[512]; int dev_fd, fd; - static char ldlinux_name[] = "@:\\LDLINUX.SYS"; + static char ldlinux_name[] = "@:\\ldlinux.sys"; char **argp, *opt; int force = 0; /* -f (force) option */ struct libfat_filesystem *fs; @@ -461,6 +488,7 @@ int main(int argc, char *argv[]) int i; int writembr = 0; /* -m (write MBR) option */ int set_active = 0; /* -a (set partition active) option */ + const char *subdir = NULL; dprintf("argv = %p\n", argv); for ( i = 0 ; i <= argc ; i++ ) @@ -490,6 +518,10 @@ int main(int argc, char *argv[]) case 'a': /* Set partition active */ set_active = 1; break; + case 'd': + if ( opt[1] ) + subdir = ++opt; + break; default: usage(); } @@ -558,6 +590,42 @@ int main(int argc, char *argv[]) libfat_close(fs); /* + * If requested, move ldlinux.sys + */ + if (subdir) { + char new_ldlinux_name[160]; + char *cp = new_ldlinux_name+3; + const char *sd; + int slash = 1; + + new_ldlinux_name[0] = dev_fd | 0x40; + new_ldlinux_name[1] = ':'; + new_ldlinux_name[2] = '\\'; + + for (sd = subdir; *sd; sd++) { + if (*sd == '/' || *sd == '\\') { + if (slash) + continue; + *cp++ = '\\'; + } + } + + /* Skip if subdirectory == root */ + if (cp > new_ldlinux_name+3) { + if (!slash) + *cp++ = '\\'; + + memcpy(cp, "ldlinux.sys", 12); + + set_attributes(ldlinux_name, 0); + if (rename(ldlinux_name, new_ldlinux_name)) + set_attributes(ldlinux_name, 0x07); + else + set_attributes(new_ldlinux_name, 0x07); + } + } + + /* * Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors); |