diff options
| -rw-r--r-- | extlinux/main.c | 2 | ||||
| -rw-r--r-- | libinstaller/syslxopt.c | 33 | ||||
| -rw-r--r-- | libinstaller/syslxopt.h | 5 | ||||
| -rw-r--r-- | linux/syslinux.c | 2 | ||||
| -rw-r--r-- | mtools/Makefile | 1 | ||||
| -rw-r--r-- | mtools/syslinux.c | 88 | ||||
| -rw-r--r-- | win32/Makefile | 1 | ||||
| -rw-r--r-- | win32/sysexits.h | 1 | ||||
| -rw-r--r-- | win32/syslinux.c | 110 |
9 files changed, 100 insertions, 143 deletions
diff --git a/extlinux/main.c b/extlinux/main.c index daebc101..a541e38a 100644 --- a/extlinux/main.c +++ b/extlinux/main.c @@ -809,7 +809,7 @@ int main(int argc, char *argv[]) { parse_options(argc, argv, MODE_EXTLINUX); - if (!opt.directory) + if (!opt.directory || opt.install_mbr || opt.activate_partition || opt.force) usage(EX_USAGE, 0); if (opt.update_only == -1) { diff --git a/libinstaller/syslxopt.c b/libinstaller/syslxopt.c index 0ff2efbb..e7f405a1 100644 --- a/libinstaller/syslxopt.c +++ b/libinstaller/syslxopt.c @@ -40,10 +40,14 @@ struct sys_options opt = { .device = NULL, .offset = 0, .menu_save = NULL, + .install_mbr = 0, + .activate_partition = 0, + .force = 0, + .bootsecfile = NULL, }; const struct option long_options[] = { - {"force", 0, NULL, 'f'}, /* dummy option for compatibility */ + {"force", 0, NULL, 'f'}, /* DOS/Win32/mtools only */ {"install", 0, NULL, 'i'}, {"directory", 1, NULL, 'd'}, {"offset", 1, NULL, 't'}, @@ -59,10 +63,12 @@ const struct option long_options[] = { {"clear-once", 0, NULL, 'O'}, {"reset-adv", 0, NULL, OPT_RESET_ADV}, {"menu-save", 1, NULL, 'M'}, + {"mbr", 0, NULL, 'm'}, /* DOS/Win32 only */ + {"active", 0, NULL, 'a'}, /* DOS/Win32 only */ {0, 0, 0, 0} }; -const char short_options[] = "t:fid:UuzS:H:rvho:OM:"; +const char short_options[] = "t:fid:UuzS:H:rvho:OM:ma"; void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode) { @@ -83,6 +89,13 @@ void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode) "Usage: %s [options] directory\n", program); break; + + case MODE_SYSLINUX_DOSWIN: + /* For fs installation under Windows (syslinux.exe) */ + fprintf(stderr, + "Usage: %s [options] <drive>: [bootsecfile]\n", + program); + break; } fprintf(stderr, @@ -97,6 +110,9 @@ void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode) " --clear-once -O Clear the boot-once command\n" " --reset-adv Reset auxilliary data\n" " --menu-save= -M Set the label to select as default on the next boot\n" + " --mbr -m Install an MBR (DOS/Win32 installers only)\n" + " --active -a Mark partition as active (DOS/Win32 installers only)\n" + " --force -f Ignore precautions (DOS/Win32/mtools installers only)\n" "\n" " Note: geometry is determined at boot time for devices which\n" " are considered hard disks by the BIOS. Unfortunately, this is\n" @@ -105,7 +121,7 @@ void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode) "\n" " The -z option is useful for USB devices which are considered\n" " hard disks by some BIOSes and zipdrives by other BIOSes.\n", - mode == MODE_SYSLINUX ? " " : "-o"); + mode == MODE_SYSLINUX ? " " : "-o"); exit(rv); } @@ -119,6 +135,7 @@ void parse_options(int argc, char *argv[], enum syslinux_mode mode) long_options, NULL)) != EOF) { switch (o) { case 'f': + opt.force = 1; break; case 'z': opt.heads = 64; @@ -183,6 +200,12 @@ void parse_options(int argc, char *argv[], enum syslinux_mode mode) case 'M': opt.menu_save = optarg; break; + case 'm': + opt.install_mbr = 1; + break; + case 'a': + opt.activate_partition = 1; + break; case 'v': fprintf(stderr, "%s " VERSION_STR " Copyright 1994-" YEAR_STR @@ -196,6 +219,7 @@ void parse_options(int argc, char *argv[], enum syslinux_mode mode) switch (mode) { case MODE_SYSLINUX: + case MODE_SYSLINUX_DOSWIN: opt.device = argv[optind++]; break; case MODE_EXTLINUX: @@ -204,6 +228,9 @@ void parse_options(int argc, char *argv[], enum syslinux_mode mode) break; } + if (argv[optind] && (mode == MODE_SYSLINUX_DOSWIN)) + /* Allow for the boot-sector argument */ + opt.bootsecfile = argv[optind++]; if (argv[optind]) usage(EX_USAGE, mode); /* Excess arguments */ } diff --git a/libinstaller/syslxopt.h b/libinstaller/syslxopt.h index 446ab9af..bcbe0352 100644 --- a/libinstaller/syslxopt.h +++ b/libinstaller/syslxopt.h @@ -14,6 +14,10 @@ struct sys_options { const char *device; unsigned int offset; const char *menu_save; + int force; + int install_mbr; + int activate_partition; + const char *bootsecfile; }; enum long_only_opt { @@ -25,6 +29,7 @@ enum long_only_opt { enum syslinux_mode { MODE_SYSLINUX, /* Unmounted filesystem */ MODE_EXTLINUX, + MODE_SYSLINUX_DOSWIN, }; void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode); diff --git a/linux/syslinux.c b/linux/syslinux.c index 9462138f..9807bdf0 100644 --- a/linux/syslinux.c +++ b/linux/syslinux.c @@ -273,7 +273,7 @@ int main(int argc, char *argv[]) subdir = "/"; } - if (!opt.device) + if (!opt.device || opt.install_mbr || opt.activate_partition || opt.force) usage(EX_USAGE, MODE_SYSLINUX); /* diff --git a/mtools/Makefile b/mtools/Makefile index 70bed14c..6164d24c 100644 --- a/mtools/Makefile +++ b/mtools/Makefile @@ -9,6 +9,7 @@ LDFLAGS = -s SRCS = syslinux.c \ ../libinstaller/fat.c \ ../libinstaller/syslxmod.c \ + ../libinstaller/syslxopt.c \ ../libinstaller/setadv.c \ ../libinstaller/bootsect_bin.c \ ../libinstaller/ldlinux_bin.c \ diff --git a/mtools/syslinux.c b/mtools/syslinux.c index 76cd2ca4..b5f52000 100644 --- a/mtools/syslinux.c +++ b/mtools/syslinux.c @@ -23,12 +23,14 @@ #include <alloca.h> #include <errno.h> #include <fcntl.h> +#include <getopt.h> #include <inttypes.h> #include <mntent.h> #include <paths.h> #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <sysexits.h> #include <syslog.h> #include <unistd.h> #include <sys/types.h> @@ -38,18 +40,10 @@ #include "syslinux.h" #include "libfat.h" #include "setadv.h" +#include "syslxopt.h" char *program; /* Name of program */ -char *device; /* Device to install to */ pid_t mypid; -off_t filesystem_offset = 0; /* Offset of filesystem */ - -void __attribute__ ((noreturn)) usage(void) -{ - fprintf(stderr, "Usage: %s [-sfr][-d directory][-o offset] device\n", - program); - exit(1); -} void __attribute__ ((noreturn)) die(const char *msg) { @@ -126,7 +120,7 @@ ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) int libfat_xpread(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sector) { - off_t offset = (off_t) sector * secsize + filesystem_offset; + off_t offset = (off_t) sector * secsize + opt.offset; return xpread(pp, buf, secsize, offset); } @@ -136,10 +130,8 @@ int main(int argc, char *argv[]) int dev_fd; struct stat st; int status; - char **argp, *opt; const char *tmpdir; char *mtools_conf; - const char *subdir = NULL; int mtc_fd; FILE *mtc, *mtp; struct libfat_filesystem *fs; @@ -151,48 +143,23 @@ int main(int argc, char *argv[]) int ldlinux_sectors, patch_sectors; int i; - int force = 0; /* -f (force) option */ - int stupid = 0; /* -s (stupid) option */ - int raid_mode = 0; /* -r (RAID) option */ - (void)argc; /* Unused */ mypid = getpid(); program = argv[0]; - device = NULL; - - for (argp = argv + 1; *argp; argp++) { - if (**argp == '-') { - opt = *argp + 1; - if (!*opt) - usage(); - - while (*opt) { - if (*opt == 's') { - stupid = 1; - } else if (*opt == 'r') { - raid_mode = 1; - } else if (*opt == 'f') { - force = 1; /* Force install */ - } else if (*opt == 'd' && argp[1]) { - subdir = *++argp; - } else if (*opt == 'o' && argp[1]) { - filesystem_offset = (off_t) strtoull(*++argp, NULL, 0); /* Byte offset */ - } else { - usage(); - } - opt++; - } - } else { - if (device) - usage(); - device = *argp; - } - } + parse_options(argc, argv, MODE_SYSLINUX); + + if (!opt.device) + usage(EX_USAGE, MODE_SYSLINUX); - if (!device) - usage(); + if (opt.sectors || opt.heads || opt.reset_adv || opt.set_once + || (opt.update_only > 0) || opt.menu_save) { + fprintf(stderr, + "At least one specified option not yet implemented" + " for this installer.\n"); + exit(1); + } /* * Temp directory of choice... @@ -212,20 +179,20 @@ int main(int argc, char *argv[]) * First make sure we can open the device at all, and that we have * read/write permission. */ - dev_fd = open(device, O_RDWR); + dev_fd = open(opt.device, O_RDWR); if (dev_fd < 0 || fstat(dev_fd, &st) < 0) { - die_err(device); + die_err(opt.device); exit(1); } - if (!force && !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode)) { + if (!opt.force && !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode)) { fprintf(stderr, "%s: not a block device or regular file (use -f to override)\n", - device); + opt.device); exit(1); } - xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); + xpread(dev_fd, sectbuf, SECTOR_SIZE, opt.offset); /* * Check to see that what we got was indeed an MS-DOS boot sector/superblock @@ -253,7 +220,7 @@ int main(int argc, char *argv[]) " file=\"/proc/%lu/fd/%d\"\n" " offset=%llu\n", (unsigned long)mypid, - dev_fd, (unsigned long long)filesystem_offset); + dev_fd, (unsigned long long)opt.offset); if (ferror(mtc) || fclose(mtc)) die_err(mtools_conf); @@ -303,24 +270,25 @@ int main(int argc, char *argv[]) libfat_close(fs); /* Patch ldlinux.sys and the boot sector */ - i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir, NULL); + i = syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, + opt.directory, NULL); patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT; /* Write the now-patched first sectors of ldlinux.sys */ for (i = 0; i < patch_sectors; i++) { xpwrite(dev_fd, syslinux_ldlinux + i * SECTOR_SIZE, SECTOR_SIZE, - filesystem_offset + ((off_t) sectors[i] << SECTOR_SHIFT)); + opt.offset + ((off_t) sectors[i] << SECTOR_SHIFT)); } /* Move ldlinux.sys to the desired location */ - if (subdir) { + if (opt.directory) { char target_file[4096], command[5120]; char *cp = target_file, *ep = target_file + sizeof target_file - 16; const char *sd; int slash = 1; cp += sprintf(cp, "'s:/"); - for (sd = subdir; *sd; sd++) { + for (sd = opt.directory; *sd; sd++) { if (*sd == '/' || *sd == '\\') { if (slash) continue; /* Remove duplicated slashes */ @@ -384,13 +352,13 @@ int main(int argc, char *argv[]) */ /* Read the superblock again since it might have changed while mounted */ - xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); + xpread(dev_fd, sectbuf, SECTOR_SIZE, opt.offset); /* Copy the syslinux code into the boot sector */ syslinux_make_bootsect(sectbuf); /* Write new boot sector */ - xpwrite(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); + xpwrite(dev_fd, sectbuf, SECTOR_SIZE, opt.offset); close(dev_fd); sync(); diff --git a/win32/Makefile b/win32/Makefile index a077b30c..81a6e9ec 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -49,6 +49,7 @@ SRCS = syslinux.c OBJS = $(patsubst %.c,%.obj,$(notdir $(SRCS))) LIBSRC = ../libinstaller/fat.c \ ../libinstaller/syslxmod.c \ + ../libinstaller/syslxopt.c \ ../libinstaller/setadv.c \ ../libinstaller/bootsect_bin.c \ ../libinstaller/ldlinux_bin.c \ diff --git a/win32/sysexits.h b/win32/sysexits.h new file mode 100644 index 00000000..483d3bab --- /dev/null +++ b/win32/sysexits.h @@ -0,0 +1 @@ +#define EX_USAGE 0x40 diff --git a/win32/syslinux.c b/win32/syslinux.c index ca98d78b..94593859 100644 --- a/win32/syslinux.c +++ b/win32/syslinux.c @@ -20,10 +20,13 @@ #include <windows.h> #include <stdio.h> #include <ctype.h> +#include <getopt.h> #include "syslinux.h" #include "libfat.h" #include "setadv.h" +#include "sysexits.h" +#include "syslxopt.h" #ifdef __GNUC__ # define noreturn void __attribute__((noreturn)) @@ -168,7 +171,6 @@ BOOL FixMBR(int driveNum, int partitionNum, int write_mbr, int set_active) /* End stuff for MBR code */ const char *program; /* Name of program */ -const char *drive; /* Drive to install to */ /* * Check Windows version. @@ -229,13 +231,6 @@ int libfat_readfile(intptr_t pp, void *buf, size_t secsize, return secsize; } -noreturn usage(void) -{ - fprintf(stderr, - "Usage: syslinux.exe [-sfmar][-d directory] <drive>: [bootsecfile]\n"); - exit(1); -} - int main(int argc, char *argv[]) { HANDLE f_handle, d_handle; @@ -245,7 +240,7 @@ int main(int argc, char *argv[]) UINT drive_type; static unsigned char sectbuf[SECTOR_SIZE]; - char **argp, *opt; + char **argp; static char drive_name[] = "\\\\.\\?:"; static char drive_root[] = "?:\\"; static char ldlinux_name[] = "?:\\ldlinux.sys"; @@ -256,14 +251,6 @@ int main(int argc, char *argv[]) int ldlinux_sectors; uint32_t ldlinux_cluster; int nsectors; - const char *bootsecfile = NULL; - const char *subdir = NULL; - - int force = 0; /* -f (force) option */ - int mbr = 0; /* -m (MBR) option */ - int setactive = 0; /* -a (set partition active) */ - int stupid = 0; /* -s (stupid) option */ - int raid_mode = 0; /* -r (RAID) option */ (void)argc; @@ -274,69 +261,36 @@ int main(int argc, char *argv[]) } program = argv[0]; - drive = NULL; - - for (argp = argv + 1; *argp; argp++) { - if (**argp == '-') { - opt = *argp + 1; - if (!*opt) - usage(); - - while (*opt) { - switch (*opt) { - case 's': /* Use "safe, slow and stupid" code */ - stupid = 1; - break; - case 'r': /* RAID mode */ - raid_mode = 1; - break; - case 'f': /* Force install */ - force = 1; - break; - case 'm': /* Install MBR */ - mbr = 1; - break; - case 'a': /* Mark this partition active */ - setactive = 1; - break; - case 'd': - if (argp[1]) - subdir = *++argp; - break; - default: - usage(); - break; - } - opt++; - } - } else { - if (bootsecfile) - usage(); - else if (drive) - bootsecfile = *argp; - else - drive = *argp; - } - } - if (!drive || !isalpha(drive[0]) || drive[1] != ':' || drive[2]) - usage(); + parse_options(argc, argv, MODE_SYSLINUX_DOSWIN); + + if (!opt.device || !isalpha(opt.device[0]) || opt.device[1] != ':' + || opt.device[2]) + usage(EX_USAGE, MODE_SYSLINUX_DOSWIN); + + if (opt.sectors || opt.heads || opt.reset_adv || opt.set_once + || (opt.update_only > 0) || opt.menu_save || opt.offset) { + fprintf(stderr, + "At least one specified option not yet implemented" + " for this installer.\n"); + exit(1); + } /* Test if drive exists */ drives = GetLogicalDrives(); - if (!(drives & (1 << (tolower(drive[0]) - 'a')))) { - fprintf(stderr, "No such drive %c:\n", drive[0]); + if (!(drives & (1 << (tolower(opt.device[0]) - 'a')))) { + fprintf(stderr, "No such drive %c:\n", opt.device[0]); exit(1); } /* Determines the drive type */ - drive_name[4] = drive[0]; - ldlinux_name[0] = drive[0]; - drive_root[0] = drive[0]; + drive_name[4] = opt.device[0]; + ldlinux_name[0] = opt.device[0]; + drive_root[0] = opt.device[0]; drive_type = GetDriveType(drive_root); /* Test for removeable media */ - if ((drive_type == DRIVE_FIXED) && (force == 0)) { + if ((drive_type == DRIVE_FIXED) && (opt.force == 0)) { fprintf(stderr, "Not a removable drive (use -f to override) \n"); exit(1); } @@ -439,7 +393,7 @@ int main(int argc, char *argv[]) /* * Patch ldlinux.sys and the boot sector */ - syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir, NULL); + syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, opt.directory, NULL); /* * Rewrite the file @@ -453,10 +407,10 @@ int main(int argc, char *argv[]) } /* If desired, fix the MBR */ - if (mbr || setactive) { + if (opt.install_mbr || opt.activate_partition) { STORAGE_DEVICE_NUMBER sdn; if (GetStorageDeviceNumberByHandle(d_handle, &sdn)) { - if (!FixMBR(sdn.DeviceNumber, sdn.PartitionNumber, mbr, setactive)) { + if (!FixMBR(sdn.DeviceNumber, sdn.PartitionNumber, opt.install_mbr, opt.activate_partition)) { fprintf(stderr, "Did not successfully update the MBR; continuing...\n"); } @@ -470,17 +424,17 @@ int main(int argc, char *argv[]) CloseHandle(f_handle); /* Move the file to the desired location */ - if (subdir) { - char new_ldlinux_name[strlen(subdir) + 16]; + 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] = drive[0]; + new_ldlinux_name[0] = opt.device[0]; new_ldlinux_name[1] = ':'; new_ldlinux_name[2] = '\\'; - for (sd = subdir; *sd; sd++) { + for (sd = opt.directory; *sd; sd++) { char c = *sd; if (c == '/' || c == '\\') { @@ -520,8 +474,8 @@ int main(int argc, char *argv[]) syslinux_make_bootsect(sectbuf); /* Write the syslinux boot sector into the boot sector */ - if (bootsecfile) { - f_handle = CreateFile(bootsecfile, GENERIC_READ | GENERIC_WRITE, + if (opt.bootsecfile) { + f_handle = CreateFile(opt.bootsecfile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); |
