chain.c32: use a more Linux-kernel-like syntax
authorH. Peter Anvin <hpa@zytor.com>
Fri, 20 Jun 2008 23:09:13 +0000 (16:09 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 20 Jun 2008 23:09:13 +0000 (16:09 -0700)
Make the syntax for chain.c32 more Linux-kernel-like.  This also makes
parsing easier, so it's a win all around.

NEWS
com32/modules/chain.c

diff --git a/NEWS b/NEWS
index a70bdaa..1b2e582 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -30,19 +30,23 @@ Changes in 3.70:
          common extended formats, but it is still possible some very
          exotic formats need geometry specification.  Large floppies
          and very small harddisks still need explicit specification.
-       * chain.c32: option -swap to support swapping of BIOS drive
+       * chain.c32: option "swap" to support swapping of BIOS drive
          numbers.  This is necessary to boot certain operating systems
          (DOS, Windows) from a secondary drive.
-       * chain.c32: option -file to support loading a boot file from
+       * chain.c32: option "file=" to support loading a boot file from
          the SYSLINUX filesystem instead of loading the boot sector
          from the drive.
-       * chain.c32: option -seg to control the load location.
-       * chain.c32: option -ntldr as a shorthand for "-seg 0x2000
-         -file"; use this to load one of WinNT's loaders:
+       * chain.c32: option "seg=" to control the load location.
+       * chain.c32: option "ntldr=" as a shorthand for "seg=0x2000
+         file="; use this to load one of WinNT's loaders:
 
-         chain.c32 hd0 1 -ntldr /MiniNT/setupldr.bin
+         chain.c32 hd0 1 ntldr=/MiniNT/setupldr.bin
 
          Note that the file needs to be in the SYSLINUX filesystem.
+       * chain.32: options "freedos=" and "msdos="/"pcdos=" as
+         shorthands for "seg=0x60 file=" and "seg=0x70 file="
+         respectively; use this to load FreeDOS's kernel.sys, MS-DOS's
+         io.sys or PC-DOS's ibmbio.sys.
 
 Changes in 3.64:
        * SYSLINUX/EXTLINUX: support "localboot" with the same feature
index e4aa69b..e669961 100644 (file)
@@ -528,7 +528,7 @@ enomem:
 
 int main(int argc, char *argv[])
 {
-  char *mbr;
+  char *mbr, *p;
   void *boot_sector = NULL;
   struct part_entry *partinfo;
   struct syslinux_rm_regs regs;
@@ -546,41 +546,46 @@ int main(int argc, char *argv[])
   memset(&regs, 0, sizeof regs);
 
   for (i = 1; i < argc; i++) {
-    if (!strcmp(argv[i], "-file") && argv[i+1]) {
-      opt.loadfile = argv[++i];
-    } else if (!strcmp(argv[i], "-seg") && argv[i+1]) {
-      uint32_t segval = strtoul(argv[++i], NULL, 0);
+    if (!strncmp(argv[i], "file=", 5)) {
+      opt.loadfile = argv[i]+5;
+    } else if (!strncmp(argv[i], "seg=", 4)) {
+      uint32_t segval = strtoul(argv[i]+4, NULL, 0);
       if (segval < 0x50 || segval > 0x9f000) {
        error("Invalid segment");
        goto bail;
       }
       opt.seg = segval;
-    } else if (!strcmp(argv[i], "-ntldr") && argv[i+1]) {
+    } else if (!strncmp(argv[i], "ntldr=", 6)) {
       opt.seg = 0x2000;                /* NTLDR wants this address */
-      opt.loadfile = argv[++i];
-    } else if (!strcmp(argv[i], "-freedos") && argv[i+1]) {
+      opt.loadfile = argv[i]+6;
+    } else if (!strncmp(argv[i], "freedos=", 8)) {
       opt.seg = 0x60;          /* FREEDOS wants this address */
-      opt.loadfile = argv[++i];
-    } else if (!strcmp(argv[i], "-msdos") && argv[i+1]) {
+      opt.loadfile = argv[i]+8;
+    } else if (!strncmp(argv[i], "msdos=", 6) ||
+              !strncmp(argv[i], "pcdos=", 6)) {
       opt.seg = 0x70;          /* MS-DOS 2.0+ wants this address */
-      opt.loadfile = argv[++i];
-    } else if (!strcmp(argv[i], "-swap")) {
+      opt.loadfile = argv[i]+6;
+    } else if (!strcmp(argv[i], "swap")) {
       opt.swap = true;
     } else if (!strcmp(argv[i], "keeppxe")) {
       opt.keeppxe = 3;
+    } else if (((argv[i][0] == 'h' || argv[i][0] == 'f') && argv[i][1] == 'd')
+              || !strncmp(argv[i], "mbr:", 4)
+              || !strncmp(argv[i], "mbr=", 4)) {
+      drivename = argv[i];
+      p = strchr(drivename, ',');
+      if (p) {
+       *p = '\0';
+       partition = p+1;
+      } else if (argv[i+1] && argv[i+1][0] >= '0' && argv[i+1][0] <= '9') {
+       partition = argv[++i];
+      }
     } else {
-      if (!drivename)
-       drivename = argv[i];
-      else if (!partition)
-       partition = argv[i];
+      error("Usage: chain.c32 (hd#|fd#|mbr:#)[,partition] [options]\n");
+      goto bail;
     }
   }
 
-  if ( !drivename ) {
-    error("Usage: chain.c32 (hd#|fd#|mbr:#) [partition] [options]\n");
-    goto bail;
-  }
-
   if (opt.seg) {
     regs.es = regs.cs = regs.ss = regs.ds = regs.fs = regs.gs = opt.seg;
   } else {
@@ -598,7 +603,7 @@ int main(int argc, char *argv[])
   partition = argv[2];         /* Possibly null */
 
   hd = 0;
-  if ( !memcmp(drivename, "mbr:", 4) ) {
+  if ( !strncmp(drivename, "mbr", 3) ) {
     drive = find_disk(strtoul(drivename+4, NULL, 0), mbr);
     if (drive == -1) {
       error("Unable to find requested MBR signature\n");