aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-07-19 10:48:15 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-07-19 10:48:15 -0700
commitd083811efff31d3dec9ca95fb3380b72274e85ef (patch)
tree536a8103d7029bc6fa855ef00e92a5273273a1c9
parent9c2baed55c657e68b5d2aa7de7557eccfc74eb6b (diff)
parente514447e3a4506468b1d066b3bd00f0d32df265a (diff)
downloadhdt-pierre-d083811efff31d3dec9ca95fb3380b72274e85ef.tar.gz
hdt-pierre-d083811efff31d3dec9ca95fb3380b72274e85ef.tar.xz
hdt-pierre-d083811efff31d3dec9ca95fb3380b72274e85ef.zip
Merge remote branch 'sha0/for_hpa'
-rw-r--r--extlinux/main.c2
-rw-r--r--libinstaller/syslxopt.c33
-rw-r--r--libinstaller/syslxopt.h5
-rw-r--r--linux/syslinux.c2
-rw-r--r--mtools/Makefile1
-rw-r--r--mtools/syslinux.c88
-rw-r--r--win32/Makefile1
-rw-r--r--win32/sysexits.h1
-rw-r--r--win32/syslinux.c110
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);