[syslinux:master] utils/isohybrid.c: Introduce option --mbr and make isohybrid.c compilable standalone

syslinux-bot for Thomas Schmitt scdbackup at gmx.net
Mon Jun 23 20:09:07 PDT 2014


Commit-ID:  9b32a80b97e1ad976d304c3940f50e8d66c158b8
Gitweb:     http://www.syslinux.org/commit/9b32a80b97e1ad976d304c3940f50e8d66c158b8
Author:     Thomas Schmitt <scdbackup at gmx.net>
AuthorDate: Sun, 22 Jun 2014 22:24:22 +0200
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Mon, 23 Jun 2014 19:48:59 -0700

utils/isohybrid.c: Introduce option --mbr and make isohybrid.c compilable standalone

Although isohybrid.c is supposed to be a companion of the local SYSLINUX
installation, there may be situations where the file isolinux.bin and the
matching MBR template do not stem directly from such an installation.

This change adds an option --mbr, which allows to load an MBR template
file. This may be an isohdp[fp]x*.bin MBR template from the local SYSLINUX
installation, or the first 512 bytes of the isohybrid-capable ISO image
from which isolinux.bin and the other ISOLINUX files are taken.

If macro ISOHYBRID_C_STANDALONE is defined, then the hardcoded MBR templates
are not accessible and isohdpfx.o is not needed at compile time. In this
case, option --mbr becomes mandatory.
I used this for testing my changes with Fedora-Live-Desktop-x86_64-20-1.iso.

isohybrid.c is then compilable without further components of ISOLINUX by:

  cc -DISOHYBRID_C_STANDALONE -Wall -o isohybrid isohybrid.c -luuid

Test run:

  cp Fedora-Live-Desktop-x86_64-20-1.iso \
     Fedora-Live-Desktop-x86_64-20-1-rehybrid.iso

  valgrind ./isohybrid --uefi --mac \
           --mbr Fedora-Live-Desktop-x86_64-20-1.mbr \
           Fedora-Live-Desktop-x86_64-20-1-rehybrid.iso

yields:

  ==13828== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 1)
  ...
  ==13828== LEAK SUMMARY:
  ==13828==    definitely lost: 2,048 bytes in 1 blocks.

(Not that valgrind would have detected the memcpy() abuse of patch 001.
 But at least i seem to have not introduced more obvious sins.)

Signed-off-by: H. Peter Anvin <hpa at zytor.com>

---
 utils/isohybrid.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index 072402f..0011b78 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -63,6 +63,8 @@ uint32_t id = 0;                /* MBR: 0 <= id <= 0xFFFFFFFF(4294967296) */
 uint8_t hd0 = 0;                /* 0 <= hd0 <= 2 */
 uint8_t partok = 0;             /* 0 <= partok <= 1 */
 
+char mbr_template_path[1024] = {0};   /* Path to MBR template */
+
 uint16_t ve[16];
 uint32_t catoffset = 0;
 uint32_t c = 0, cc = 0, cs = 0;
@@ -223,7 +225,7 @@ usage(void)
 void
 printh(void)
 {
-#define FMT "%-18s %s\n"
+#define FMT "%-20s %s\n"
 
     usage();
 
@@ -237,6 +239,7 @@ printh(void)
     printf(FMT, "   -i --id", "Specify MBR ID (default random)");
     printf(FMT, "   -u --uefi", "Build EFI bootable image");
     printf(FMT, "   -m --mac", "Add AFP table support");
+    printf(FMT, "   -b --mbr <PATH>", "Load MBR from PATH");
 
     printf("\n");
     printf(FMT, "   --forcehd0", "Assume we are loaded as disk ID 0");
@@ -272,6 +275,7 @@ check_option(int argc, char *argv[])
         { "partok", no_argument, NULL, 'p'},
 	{ "uefi", no_argument, NULL, 'u'},
 	{ "mac", no_argument, NULL, 'm'},
+        { "mbr", required_argument, NULL, 'b' },
 
         { "help", no_argument, NULL, '?' },
         { "verbose", no_argument, NULL, 'v' },
@@ -347,6 +351,12 @@ check_option(int argc, char *argv[])
 		errx(1, "setting an entry is unsupported with EFI or Mac");
 	    break;
 
+	case 'b':
+            if (strlen(optarg) >= sizeof(mbr_template_path))
+                errx(1, "--mbr : Path too long");
+            strcpy(mbr_template_path, optarg);
+            break;
+
         case 'v':
             mode |= VERBOSE;
             break;
@@ -571,6 +581,24 @@ display_catalogue(void)
     printf("de_mbz2: %hu\n", de_mbz2);
 }
 
+
+void
+read_mbr_template(char *path, uint8_t *mbr)
+{
+    FILE *fp;
+    int ret;
+
+    fp = fopen(path, "rb");
+    if (fp == NULL)
+        err(1, "could not open MBR template file `%s'", path);
+    clearerr(fp);
+    ret = fread(mbr, 1, MBRSIZE, fp);
+    if (ferror(fp))
+        err(1, "error while reading MBR template file `%s'", path);
+    fclose(fp);
+}
+
+
 int
 initialise_mbr(uint8_t *mbr)
 {
@@ -580,9 +608,25 @@ initialise_mbr(uint8_t *mbr)
     uint8_t bhead = 0, bsect = 0, bcyle = 0;
     uint8_t ehead = 0, esect = 0, ecyle = 0;
 
+#ifndef ISOHYBRID_C_STANDALONE
     extern unsigned char isohdpfx[][MBRSIZE];
+#endif
+
+    if (mbr_template_path[0]) {
+        read_mbr_template(mbr_template_path, mbr);
+    } else {
+
+#ifdef ISOHYBRID_C_STANDALONE
+
+        err(1, "This is a standalone binary. You must specify --mbr. E.g with /usr/lib/syslinux/isohdpfx.bin");
 
-    memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE);
+#else
+
+        memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE);
+
+#endif /* ! ISOHYBRID_C_STANDALONE */
+
+    }
 
     if (mode & MAC) {
 	memcpy(mbr, afp_header, sizeof(afp_header));


More information about the Syslinux-commits mailing list