summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/libinstaller
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/libinstaller')
-rw-r--r--contrib/syslinux-4.02/libinstaller/Makefile28
l---------contrib/syslinux-4.02/libinstaller/advconst.h1
-rw-r--r--contrib/syslinux-4.02/libinstaller/advio.c162
-rwxr-xr-xcontrib/syslinux-4.02/libinstaller/bin2c.pl78
-rw-r--r--contrib/syslinux-4.02/libinstaller/fat.c129
-rw-r--r--contrib/syslinux-4.02/libinstaller/getopt/getopt.h25
-rw-r--r--contrib/syslinux-4.02/libinstaller/getopt/getopt_long.c152
-rw-r--r--contrib/syslinux-4.02/libinstaller/linux/fiemap.h68
-rw-r--r--contrib/syslinux-4.02/libinstaller/linux/loop.h96
-rw-r--r--contrib/syslinux-4.02/libinstaller/linuxioctl.h47
-rw-r--r--contrib/syslinux-4.02/libinstaller/setadv.c167
-rw-r--r--contrib/syslinux-4.02/libinstaller/setadv.h16
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslinux.h54
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslxcom.c286
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslxcom.h22
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslxint.h246
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslxmod.c197
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslxopt.c267
-rw-r--r--contrib/syslinux-4.02/libinstaller/syslxopt.h43
19 files changed, 2084 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/libinstaller/Makefile b/contrib/syslinux-4.02/libinstaller/Makefile
new file mode 100644
index 0000000..2beb931
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/Makefile
@@ -0,0 +1,28 @@
+# _bin.c files required by both BTARGET and ITARGET installers
+BINFILES = bootsect_bin.c ldlinux_bin.c \
+ mbr_bin.c gptmbr_bin.c
+
+PERL = perl
+
+all: $(BINFILES)
+
+bootsect_bin.c: ../core/ldlinux.bss bin2c.pl
+ $(PERL) bin2c.pl syslinux_bootsect < $< > $@
+
+ldlinux_bin.c: ../core/ldlinux.sys bin2c.pl
+ $(PERL) bin2c.pl syslinux_ldlinux 512 < $< > $@
+
+mbr_bin.c: ../mbr/mbr.bin bin2c.pl
+ $(PERL) bin2c.pl syslinux_mbr < $< > $@
+
+gptmbr_bin.c: ../mbr/gptmbr.bin bin2c.pl
+ $(PERL) bin2c.pl syslinux_gptmbr < $< > $@
+
+tidy:
+ rm -f $(BINFILES)
+
+clean: tidy
+
+dist: tidy
+
+spotless: clean
diff --git a/contrib/syslinux-4.02/libinstaller/advconst.h b/contrib/syslinux-4.02/libinstaller/advconst.h
new file mode 120000
index 0000000..044572b
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/advconst.h
@@ -0,0 +1 @@
+../com32/include/syslinux/advconst.h \ No newline at end of file
diff --git a/contrib/syslinux-4.02/libinstaller/advio.c b/contrib/syslinux-4.02/libinstaller/advio.c
new file mode 100644
index 0000000..56f607d
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/advio.c
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * advio.c
+ *
+ * Linux ADV I/O
+ *
+ * Return 0 on success, -1 on error, and set errno.
+ *
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "syslxint.h"
+#include "syslxcom.h"
+
+/*
+ * Read the ADV from an existing instance, or initialize if invalid.
+ * Returns -1 on fatal errors, 0 if ADV is okay, 1 if the ADV is
+ * invalid, and 2 if the file does not exist.
+ */
+int read_adv(const char *path, const char *cfg)
+{
+ char *file;
+ int fd = -1;
+ struct stat st;
+ int err = 0;
+ int rv;
+
+ rv = asprintf(&file, "%s%s%s", path,
+ path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
+
+ if (rv < 0 || !file) {
+ perror(program);
+ return -1;
+ }
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ if (errno != ENOENT) {
+ err = -1;
+ } else {
+ syslinux_reset_adv(syslinux_adv);
+ err = 2; /* Nonexistence is not a fatal error */
+ }
+ } else if (fstat(fd, &st)) {
+ err = -1;
+ } else if (st.st_size < 2 * ADV_SIZE) {
+ /* Too small to be useful */
+ syslinux_reset_adv(syslinux_adv);
+ err = 0; /* Nothing to read... */
+ } else if (xpread(fd, syslinux_adv, 2 * ADV_SIZE,
+ st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
+ err = -1;
+ } else {
+ /* We got it... maybe? */
+ err = syslinux_validate_adv(syslinux_adv) ? 1 : 0;
+ }
+
+ if (err < 0)
+ perror(file);
+
+ if (fd >= 0)
+ close(fd);
+
+ free(file);
+
+ return err;
+}
+
+/*
+ * Update the ADV in an existing installation.
+ */
+int write_adv(const char *path, const char *cfg)
+{
+ unsigned char advtmp[2 * ADV_SIZE];
+ char *file;
+ int fd = -1;
+ struct stat st, xst;
+ int err = 0;
+ int rv;
+
+ rv = asprintf(&file, "%s%s%s", path,
+ path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
+
+ if (rv < 0 || !file) {
+ perror(program);
+ return -1;
+ }
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ err = -1;
+ } else if (fstat(fd, &st)) {
+ err = -1;
+ } else if (st.st_size < 2 * ADV_SIZE) {
+ /* Too small to be useful */
+ err = -2;
+ } else if (xpread(fd, advtmp, 2 * ADV_SIZE,
+ st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
+ err = -1;
+ } else {
+ /* We got it... maybe? */
+ err = syslinux_validate_adv(advtmp) ? -2 : 0;
+ if (!err) {
+ /* Got a good one, write our own ADV here */
+ clear_attributes(fd);
+
+ /* Need to re-open read-write */
+ close(fd);
+ fd = open(file, O_RDWR | O_SYNC);
+ if (fd < 0) {
+ err = -1;
+ } else if (fstat(fd, &xst) || xst.st_ino != st.st_ino ||
+ xst.st_dev != st.st_dev || xst.st_size != st.st_size) {
+ fprintf(stderr, "%s: race condition on write\n", file);
+ err = -2;
+ }
+ /* Write our own version ... */
+ if (xpwrite(fd, syslinux_adv, 2 * ADV_SIZE,
+ st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
+ err = -1;
+ }
+
+ sync();
+ set_attributes(fd);
+ }
+ }
+
+ if (err == -2)
+ fprintf(stderr, "%s: cannot write auxilliary data (need --update)?\n",
+ file);
+ else if (err == -1)
+ perror(file);
+
+ if (fd >= 0)
+ close(fd);
+ if (file)
+ free(file);
+
+ return err;
+}
diff --git a/contrib/syslinux-4.02/libinstaller/bin2c.pl b/contrib/syslinux-4.02/libinstaller/bin2c.pl
new file mode 100755
index 0000000..07c11dd
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/bin2c.pl
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+## -----------------------------------------------------------------------
+##
+## Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+## Boston MA 02111-1307, USA; either version 2 of the License, or
+## (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+#
+# bin2c.pl: binary file to C source converter
+#
+
+eval { use bytes; };
+eval { binmode STDIN; };
+
+($table_name, $pad) = @ARGV;
+
+if ( !defined($table_name) ) {
+ print STDERR "Usage: $0 table_name [pad] < input_file > output_file\n";
+ exit 1;
+}
+
+$pad = 1 if ($pad < 1);
+
+printf "unsigned char %s[] = {\n", $table_name;
+
+$pos = 0;
+$linelen = 8;
+
+$total_len = 0;
+
+while ( ($n = read(STDIN, $data, 4096)) > 0 ) {
+ $total_len += $n;
+ for ( $i = 0 ; $i < $n ; $i++ ) {
+ $byte = substr($data, $i, 1);
+ if ( $pos >= $linelen ) {
+ print ",\n\t";
+ $pos = 0;
+ } elsif ( $pos > 0 ) {
+ print ", ";
+ } else {
+ print "\t";
+ }
+ printf("0x%02x", unpack("C", $byte));
+ $pos++;
+ }
+}
+
+$align = $total_len % $pad;
+if ($align != 0) {
+ $n = $pad - $align;
+ $total_len += $n;
+ for ( $i = 0 ; $i < $n ; $i++ ) {
+ if ( $pos >= $linelen ) {
+ print ",\n\t";
+ $pos = 0;
+ } elsif ( $pos > 0 ) {
+ print ", ";
+ } else {
+ print "\t";
+ }
+ print '0x00';
+ $pos++;
+ }
+}
+
+printf "\n};\n\nconst unsigned int %s_len = %u;\n", $table_name, $total_len;
+
+@st = stat STDIN;
+
+printf "\nconst int %s_mtime = %d;\n", $table_name, $st[9];
+
+exit 0;
diff --git a/contrib/syslinux-4.02/libinstaller/fat.c b/contrib/syslinux-4.02/libinstaller/fat.c
new file mode 100644
index 0000000..e210135
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/fat.c
@@ -0,0 +1,129 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009-2010 Intel Corporation; author H. Peter Anvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fat.c - Initial sanity check for FAT-based installers
+ */
+
+#define _XOPEN_SOURCE 500 /* Required on glibc 2.x */
+#define _BSD_SOURCE
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "syslinux.h"
+#include "syslxint.h"
+
+void syslinux_make_bootsect(void *bs)
+{
+ struct boot_sector *bootsect = bs;
+ const struct boot_sector *sbs =
+ (const struct boot_sector *)boot_sector;
+
+ memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen);
+ memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen);
+}
+
+/*
+ * Check to see that what we got was indeed an MS-DOS boot sector/superblock;
+ * Return NULL if OK and otherwise an error message;
+ */
+const char *syslinux_check_bootsect(const void *bs)
+{
+ int veryold;
+ int sectorsize;
+ long long sectors, fatsectors, dsectors;
+ long long clusters;
+ int rootdirents, clustersize;
+ const struct boot_sector *sectbuf = bs;
+
+ veryold = 0;
+
+ /* Must be 0xF0 or 0xF8..0xFF */
+ if (get_8(&sectbuf->bsMedia) != 0xF0 && get_8(&sectbuf->bsMedia) < 0xF8)
+ return "invalid media signature (not a FAT filesystem?)";
+
+ sectorsize = get_16(&sectbuf->bsBytesPerSec);
+ if (sectorsize == SECTOR_SIZE)
+ ; /* ok */
+ else if (sectorsize >= 512 && sectorsize <= 4096 &&
+ (sectorsize & (sectorsize - 1)) == 0)
+ return "unsupported sectors size";
+ else
+ return "impossible sector size";
+
+ clustersize = get_8(&sectbuf->bsSecPerClust);
+ if (clustersize == 0 || (clustersize & (clustersize - 1)))
+ return "impossible cluster size";
+
+ sectors = get_16(&sectbuf->bsSectors);
+ sectors = sectors ? sectors : get_32(&sectbuf->bsHugeSectors);
+
+ dsectors = sectors - get_16(&sectbuf->bsResSectors);
+
+ fatsectors = get_16(&sectbuf->bsFATsecs);
+ fatsectors = fatsectors ? fatsectors : get_32(&sectbuf->bs32.FATSz32);
+ fatsectors *= get_8(&sectbuf->bsFATs);
+ dsectors -= fatsectors;
+
+ rootdirents = get_16(&sectbuf->bsRootDirEnts);
+ dsectors -= (rootdirents + sectorsize / 32 - 1) / sectorsize;
+
+ if (dsectors < 0)
+ return "negative number of data sectors";
+
+ if (fatsectors == 0)
+ return "zero FAT sectors";
+
+ clusters = dsectors / clustersize;
+
+ if (clusters < 0xFFF5) {
+ /* FAT12 or FAT16 */
+
+ if (!get_16(&sectbuf->bsFATsecs))
+ return "zero FAT sectors (FAT12/16)";
+
+ if (get_8(&sectbuf->bs16.BootSignature) == 0x29) {
+ if (!memcmp(&sectbuf->bs16.FileSysType, "FAT12 ", 8)) {
+ if (clusters >= 0xFF5)
+ return "more than 4084 clusters but claims FAT12";
+ } else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT16 ", 8)) {
+ if (clusters < 0xFF5)
+ return "less than 4084 clusters but claims FAT16";
+ } else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT32 ", 8)) {
+ return "less than 65525 clusters but claims FAT32";
+ } else if (memcmp(&sectbuf->bs16.FileSysType, "FAT ", 8)) {
+ static char fserr[] =
+ "filesystem type \"????????\" not supported";
+ memcpy(fserr + 17, &sectbuf->bs16.FileSysType, 8);
+ return fserr;
+ }
+ }
+ } else if (clusters < 0x0FFFFFF5) {
+ /*
+ * FAT32...
+ *
+ * Moving the FileSysType and BootSignature was a lovely stroke
+ * of M$ idiocy...
+ */
+ if (get_8(&sectbuf->bs32.BootSignature) != 0x29 ||
+ memcmp(&sectbuf->bs32.FileSysType, "FAT32 ", 8))
+ return "missing FAT32 signature";
+ } else {
+ return "impossibly large number of clusters";
+ }
+
+ return NULL;
+}
diff --git a/contrib/syslinux-4.02/libinstaller/getopt/getopt.h b/contrib/syslinux-4.02/libinstaller/getopt/getopt.h
new file mode 100644
index 0000000..a1b74b1
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/getopt/getopt.h
@@ -0,0 +1,25 @@
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+/* (Very slightly) adapted from klibc */
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+enum {
+ no_argument = 0,
+ required_argument = 1,
+ optional_argument = 2,
+};
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+extern int getopt_long(int, char *const *, const char *,
+ const struct option *, int *);
+
+#endif /* _GETOPT_H */
diff --git a/contrib/syslinux-4.02/libinstaller/getopt/getopt_long.c b/contrib/syslinux-4.02/libinstaller/getopt/getopt_long.c
new file mode 100644
index 0000000..cd7fef5
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/getopt/getopt_long.c
@@ -0,0 +1,152 @@
+/*
+ * getopt.c
+ *
+ * getopt_long(), or at least a common subset thereof:
+ *
+ * - Option reordering is not supported
+ * - -W foo is not supported
+ * - First optstring character "-" not supported.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stddef.h>
+#include <getopt.h>
+
+char *optarg;
+int optind, opterr, optopt;
+static struct getopt_private_state {
+ const char *optptr;
+ const char *last_optstring;
+ char *const *last_argv;
+} pvt;
+
+static inline const char *option_matches(const char *arg_str,
+ const char *opt_name)
+{
+ while (*arg_str != '\0' && *arg_str != '=') {
+ if (*arg_str++ != *opt_name++)
+ return NULL;
+ }
+
+ if (*opt_name)
+ return NULL;
+
+ return arg_str;
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring,
+ const struct option *longopts, int *longindex)
+{
+ const char *carg;
+ const char *osptr;
+ int opt;
+
+ /* getopt() relies on a number of different global state
+ variables, which can make this really confusing if there is
+ more than one use of getopt() in the same program. This
+ attempts to detect that situation by detecting if the
+ "optstring" or "argv" argument have changed since last time
+ we were called; if so, reinitialize the query state. */
+
+ if (optstring != pvt.last_optstring || argv != pvt.last_argv ||
+ optind < 1 || optind > argc) {
+ /* optind doesn't match the current query */
+ pvt.last_optstring = optstring;
+ pvt.last_argv = argv;
+ optind = 1;
+ pvt.optptr = NULL;
+ }
+
+ carg = argv[optind];
+
+ /* First, eliminate all non-option cases */
+
+ if (!carg || carg[0] != '-' || !carg[1])
+ return -1;
+
+ if (carg[1] == '-') {
+ const struct option *lo;
+ const char *opt_end = NULL;
+
+ optind++;
+
+ /* Either it's a long option, or it's -- */
+ if (!carg[2]) {
+ /* It's -- */
+ return -1;
+ }
+
+ for (lo = longopts; lo->name; lo++) {
+ if ((opt_end = option_matches(carg+2, lo->name)))
+ break;
+ }
+ if (!opt_end)
+ return '?';
+
+ if (longindex)
+ *longindex = lo-longopts;
+
+ if (*opt_end == '=') {
+ if (lo->has_arg)
+ optarg = (char *)opt_end+1;
+ else
+ return '?';
+ } else if (lo->has_arg == 1) {
+ if (!(optarg = argv[optind]))
+ return '?';
+ optind++;
+ }
+
+ if (lo->flag) {
+ *lo->flag = lo->val;
+ return 0;
+ } else {
+ return lo->val;
+ }
+ }
+
+ if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) {
+ /* Someone frobbed optind, change to new opt. */
+ pvt.optptr = carg + 1;
+ }
+
+ opt = *pvt.optptr++;
+
+ if (opt != ':' && (osptr = strchr(optstring, opt))) {
+ if (osptr[1] == ':') {
+ if (*pvt.optptr) {
+ /* Argument-taking option with attached
+ argument */
+ optarg = (char *)pvt.optptr;
+ optind++;
+ } else {
+ /* Argument-taking option with non-attached
+ argument */
+ if (argv[optind + 1]) {
+ optarg = (char *)argv[optind+1];
+ optind += 2;
+ } else {
+ /* Missing argument */
+ optind++;
+ return (optstring[0] == ':')
+ ? ':' : '?';
+ }
+ }
+ return opt;
+ } else {
+ /* Non-argument-taking option */
+ /* pvt.optptr will remember the exact position to
+ resume at */
+ if (!*pvt.optptr)
+ optind++;
+ return opt;
+ }
+ } else {
+ /* Unknown option */
+ optopt = opt;
+ if (!*pvt.optptr)
+ optind++;
+ return '?';
+ }
+}
diff --git a/contrib/syslinux-4.02/libinstaller/linux/fiemap.h b/contrib/syslinux-4.02/libinstaller/linux/fiemap.h
new file mode 100644
index 0000000..d830747
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/linux/fiemap.h
@@ -0,0 +1,68 @@
+/*
+ * FS_IOC_FIEMAP ioctl infrastructure.
+ *
+ * Some portions copyright (C) 2007 Cluster File Systems, Inc
+ *
+ * Authors: Mark Fasheh <mfasheh@suse.com>
+ * Kalpak Shah <kalpak.shah@sun.com>
+ * Andreas Dilger <adilger@sun.com>
+ */
+
+#ifndef _LINUX_FIEMAP_H
+#define _LINUX_FIEMAP_H
+
+#include <linux/types.h>
+
+struct fiemap_extent {
+ __u64 fe_logical; /* logical offset in bytes for the start of
+ * the extent from the beginning of the file */
+ __u64 fe_physical; /* physical offset in bytes for the start
+ * of the extent from the beginning of the disk */
+ __u64 fe_length; /* length in bytes for this extent */
+ __u64 fe_reserved64[2];
+ __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
+ __u32 fe_reserved[3];
+};
+
+struct fiemap {
+ __u64 fm_start; /* logical offset (inclusive) at
+ * which to start mapping (in) */
+ __u64 fm_length; /* logical length of mapping which
+ * userspace wants (in) */
+ __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
+ __u32 fm_mapped_extents;/* number of extents that were mapped (out) */
+ __u32 fm_extent_count; /* size of fm_extents array (in) */
+ __u32 fm_reserved;
+ struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
+};
+
+#define FIEMAP_MAX_OFFSET (~0ULL)
+
+#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
+#define FIEMAP_FLAG_XATTR 0x00000002 /* map extended attribute tree */
+
+#define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR)
+
+#define FIEMAP_EXTENT_LAST 0x00000001 /* Last extent in file. */
+#define FIEMAP_EXTENT_UNKNOWN 0x00000002 /* Data location unknown. */
+#define FIEMAP_EXTENT_DELALLOC 0x00000004 /* Location still pending.
+ * Sets EXTENT_UNKNOWN. */
+#define FIEMAP_EXTENT_ENCODED 0x00000008 /* Data can not be read
+ * while fs is unmounted */
+#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs.
+ * Sets EXTENT_NO_BYPASS. */
+#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be
+ * block aligned. */
+#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata.
+ * Sets EXTENT_NOT_ALIGNED.*/
+#define FIEMAP_EXTENT_DATA_TAIL 0x00000400 /* Multiple files in block.
+ * Sets EXTENT_NOT_ALIGNED.*/
+#define FIEMAP_EXTENT_UNWRITTEN 0x00000800 /* Space allocated, but
+ * no data (i.e. zero). */
+#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
+ * support extents. Result
+ * merged for efficiency. */
+#define FIEMAP_EXTENT_SHARED 0x00002000 /* Space shared with other
+ * files. */
+
+#endif /* _LINUX_FIEMAP_H */
diff --git a/contrib/syslinux-4.02/libinstaller/linux/loop.h b/contrib/syslinux-4.02/libinstaller/linux/loop.h
new file mode 100644
index 0000000..90237a3
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/linux/loop.h
@@ -0,0 +1,96 @@
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
+
+/*
+ * include/linux/loop.h
+ *
+ * Written by Theodore Ts'o, 3/29/93.
+ *
+ * Copyright 1993 by Theodore Ts'o. Redistribution of this file is
+ * permitted under the GNU General Public License.
+ */
+
+#define LO_NAME_SIZE 64
+#define LO_KEY_SIZE 32
+
+
+/*
+ * Loop flags
+ */
+enum {
+ LO_FLAGS_READ_ONLY = 1,
+ LO_FLAGS_USE_AOPS = 2,
+ LO_FLAGS_AUTOCLEAR = 4,
+};
+
+#include <asm/posix_types.h> /* for __kernel_old_dev_t */
+#include <linux/types.h> /* for __u64 */
+#include <linux/version.h> /* version of Linux kernel headers */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+/* We have truly ancient Linux kernel headers installed */
+typedef __kernel_dev_t __kernel_old_dev_t;
+#endif
+
+/* Backwards compatibility version */
+struct loop_info {
+ int lo_number; /* ioctl r/o */
+ __kernel_old_dev_t lo_device; /* ioctl r/o */
+ unsigned long lo_inode; /* ioctl r/o */
+ __kernel_old_dev_t lo_rdevice; /* ioctl r/o */
+ int lo_offset;
+ int lo_encrypt_type;
+ int lo_encrypt_key_size; /* ioctl w/o */
+ int lo_flags; /* ioctl r/o */
+ char lo_name[LO_NAME_SIZE];
+ unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+ unsigned long lo_init[2];
+ char reserved[4];
+};
+
+struct loop_info64 {
+ __u64 lo_device; /* ioctl r/o */
+ __u64 lo_inode; /* ioctl r/o */
+ __u64 lo_rdevice; /* ioctl r/o */
+ __u64 lo_offset;
+ __u64 lo_sizelimit;/* bytes, 0 == max available */
+ __u32 lo_number; /* ioctl r/o */
+ __u32 lo_encrypt_type;
+ __u32 lo_encrypt_key_size; /* ioctl w/o */
+ __u32 lo_flags; /* ioctl r/o */
+ __u8 lo_file_name[LO_NAME_SIZE];
+ __u8 lo_crypt_name[LO_NAME_SIZE];
+ __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+ __u64 lo_init[2];
+};
+
+/*
+ * Loop filter types
+ */
+
+#define LO_CRYPT_NONE 0
+#define LO_CRYPT_XOR 1
+#define LO_CRYPT_DES 2
+#define LO_CRYPT_FISH2 3 /* Twofish encryption */
+#define LO_CRYPT_BLOW 4
+#define LO_CRYPT_CAST128 5
+#define LO_CRYPT_IDEA 6
+#define LO_CRYPT_DUMMY 9
+#define LO_CRYPT_SKIPJACK 10
+#define LO_CRYPT_CRYPTOAPI 18
+#define MAX_LO_CRYPT 20
+
+/*
+ * IOCTL commands --- we will commandeer 0x4C ('L')
+ */
+
+#define LOOP_SET_FD 0x4C00
+#define LOOP_CLR_FD 0x4C01
+#define LOOP_SET_STATUS 0x4C02
+#define LOOP_GET_STATUS 0x4C03
+#define LOOP_SET_STATUS64 0x4C04
+#define LOOP_GET_STATUS64 0x4C05
+#define LOOP_CHANGE_FD 0x4C06
+#define LOOP_SET_CAPACITY 0x4C07
+
+#endif
diff --git a/contrib/syslinux-4.02/libinstaller/linuxioctl.h b/contrib/syslinux-4.02/libinstaller/linuxioctl.h
new file mode 100644
index 0000000..7ef919a
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/linuxioctl.h
@@ -0,0 +1,47 @@
+/*
+ * linuxioctl.h
+ *
+ * Wrapper for Linux ioctl definitions, including workarounds
+ */
+
+#ifndef LIBINSTALLER_LINUXIOCTL_H
+#define LIBINSTALLER_LINUXIOCTL_H
+
+#include <sys/ioctl.h>
+
+#define statfs _kernel_statfs /* HACK to deal with broken 2.4 distros */
+
+#include <linux/fd.h> /* Floppy geometry */
+#include <linux/hdreg.h> /* Hard disk geometry */
+
+#include <linux/fs.h> /* FIGETBSZ, FIBMAP, FS_IOC_FIEMAP */
+#include <linux/msdos_fs.h> /* FAT_IOCTL_SET_ATTRIBUTES */
+
+#undef SECTOR_SIZE /* Defined in msdos_fs.h for no good reason */
+#undef SECTOR_BITS
+#include <linux/ext2_fs.h> /* EXT2_IOC_* */
+
+#ifndef FAT_IOCTL_GET_ATTRIBUTES
+# define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32)
+#endif
+
+#ifndef FAT_IOCTL_SET_ATTRIBUTES
+# define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32)
+#endif
+
+#include <linux/fiemap.h> /* FIEMAP definitions */
+
+#ifndef FS_IOC_FIEMAP
+# define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
+#endif
+
+#undef statfs
+
+#if defined(__linux__) && !defined(BLKGETSIZE64)
+/* This takes a u64, but the size field says size_t. Someone screwed big. */
+# define BLKGETSIZE64 _IOR(0x12,114,size_t)
+#endif
+
+#include <linux/loop.h>
+
+#endif /* LIBINSTALLER_LINUXIOCTL_H */
diff --git a/contrib/syslinux-4.02/libinstaller/setadv.c b/contrib/syslinux-4.02/libinstaller/setadv.c
new file mode 100644
index 0000000..9cf6f18
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/setadv.c
@@ -0,0 +1,167 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * setadv.c
+ *
+ * (Over)write a data item in the auxilliary data vector. To
+ * delete an item, set its length to zero.
+ *
+ * Return 0 on success, -1 on error, and set errno.
+ *
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include "syslxint.h"
+#include "syslxcom.h"
+
+unsigned char syslinux_adv[2 * ADV_SIZE];
+
+#define ADV_MAGIC1 0x5a2d2fa5 /* Head signature */
+#define ADV_MAGIC2 0xa3041767 /* Total checksum */
+#define ADV_MAGIC3 0xdd28bf64 /* Tail signature */
+
+static void cleanup_adv(unsigned char *advbuf)
+{
+ int i;
+ uint32_t csum;
+
+ /* Make sure both copies agree, and update the checksum */
+ set_32((uint32_t *) advbuf, ADV_MAGIC1);
+
+ csum = ADV_MAGIC2;
+ for (i = 8; i < ADV_SIZE - 4; i += 4)
+ csum -= get_32((uint32_t *) (advbuf + i));
+
+ set_32((uint32_t *) (advbuf + 4), csum);
+ set_32((uint32_t *) (advbuf + ADV_SIZE - 4), ADV_MAGIC3);
+
+ memcpy(advbuf + ADV_SIZE, advbuf, ADV_SIZE);
+}
+
+int syslinux_setadv(int tag, size_t size, const void *data)
+{
+ uint8_t *p;
+ size_t left;
+ uint8_t advtmp[ADV_SIZE];
+
+ if ((unsigned)tag - 1 > 254) {
+ errno = EINVAL;
+ return -1; /* Impossible tag value */
+ }
+
+ if (size > 255) {
+ errno = ENOSPC; /* Max 255 bytes for a data item */
+ return -1;
+ }
+
+ left = ADV_LEN;
+ p = advtmp;
+ memcpy(p, syslinux_adv + 2 * 4, left); /* Make working copy */
+
+ while (left >= 2) {
+ uint8_t ptag = p[0];
+ size_t plen = p[1] + 2;
+
+ if (ptag == ADV_END)
+ break;
+
+ if (ptag == tag) {
+ /* Found our tag. Delete it. */
+
+ if (plen >= left) {
+ /* Entire remainder is our tag */
+ break;
+ }
+ memmove(p, p + plen, left - plen);
+ } else {
+ /* Not our tag */
+ if (plen > left)
+ break; /* Corrupt tag (overrun) - overwrite it */
+
+ left -= plen;
+ p += plen;
+ }
+ }
+
+ /* Now (p, left) reflects the position to write in and how much space
+ we have for our data. */
+
+ if (size) {
+ if (left < size + 2) {
+ errno = ENOSPC; /* Not enough space for data */
+ return -1;
+ }
+
+ *p++ = tag;
+ *p++ = size;
+ memcpy(p, data, size);
+ p += size;
+ left -= size + 2;
+ }
+
+ memset(p, 0, left);
+
+ /* If we got here, everything went OK, commit the write */
+ memcpy(syslinux_adv + 2 * 4, advtmp, ADV_LEN);
+ cleanup_adv(syslinux_adv);
+
+ return 0;
+}
+
+void syslinux_reset_adv(unsigned char *advbuf)
+{
+ /* Create an all-zero ADV */
+ memset(advbuf + 2 * 4, 0, ADV_LEN);
+ cleanup_adv(advbuf);
+}
+
+static int adv_consistent(const unsigned char *p)
+{
+ int i;
+ uint32_t csum;
+
+ if (get_32((uint32_t *) p) != ADV_MAGIC1 ||
+ get_32((uint32_t *) (p + ADV_SIZE - 4)) != ADV_MAGIC3)
+ return 0;
+
+ csum = 0;
+ for (i = 4; i < ADV_SIZE - 4; i += 4)
+ csum += get_32((uint32_t *) (p + i));
+
+ return csum == ADV_MAGIC2;
+}
+
+/*
+ * Verify that an in-memory ADV is consistent, making the copies consistent.
+ * If neither copy is OK, return -1 and call syslinux_reset_adv().
+ */
+int syslinux_validate_adv(unsigned char *advbuf)
+{
+ if (adv_consistent(advbuf + 0 * ADV_SIZE)) {
+ memcpy(advbuf + ADV_SIZE, advbuf, ADV_SIZE);
+ return 0;
+ } else if (adv_consistent(advbuf + 1 * ADV_SIZE)) {
+ memcpy(advbuf, advbuf + ADV_SIZE, ADV_SIZE);
+ return 0;
+ } else {
+ syslinux_reset_adv(advbuf);
+ return -1;
+ }
+}
diff --git a/contrib/syslinux-4.02/libinstaller/setadv.h b/contrib/syslinux-4.02/libinstaller/setadv.h
new file mode 100644
index 0000000..32bdfec
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/setadv.h
@@ -0,0 +1,16 @@
+#ifndef _H_SET_ADV_
+#define _H_SET_ADV_
+
+/* ADV information */
+#define ADV_SIZE 512 /* Total size */
+#define ADV_LEN (ADV_SIZE-3*4) /* Usable data size */
+
+extern unsigned char syslinux_adv[2 * ADV_SIZE];
+
+int syslinux_setadv(int tag, size_t size, const void *data);
+void syslinux_reset_adv(unsigned char *advbuf);
+int syslinux_validate_adv(unsigned char *advbuf);
+int read_adv(const char *path, const char *cfg);
+int write_adv(const char *path, const char *cfg);
+
+#endif
diff --git a/contrib/syslinux-4.02/libinstaller/syslinux.h b/contrib/syslinux-4.02/libinstaller/syslinux.h
new file mode 100644
index 0000000..710d30e
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslinux.h
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef SYSLINUX_H
+#define SYSLINUX_H
+
+#include <inttypes.h>
+#include "advconst.h"
+#include "setadv.h"
+
+/* The standard boot sector and ldlinux image */
+extern unsigned char syslinux_bootsect[];
+extern const unsigned int syslinux_bootsect_len;
+extern const int syslinux_bootsect_mtime;
+
+extern unsigned char syslinux_ldlinux[];
+extern const unsigned int syslinux_ldlinux_len;
+extern const int syslinux_ldlinux_mtime;
+
+#define boot_sector syslinux_bootsect
+#define boot_sector_len syslinux_bootsect_len
+#define boot_image syslinux_ldlinux
+#define boot_image_len syslinux_ldlinux_len
+
+extern unsigned char syslinux_mbr[];
+extern const unsigned int syslinux_mbr_len;
+extern const int syslinux_mbr_mtime;
+
+/* Sector size assumptions... */
+#define SECTOR_SHIFT 9
+#define SECTOR_SIZE (1 << SECTOR_SHIFT)
+
+/* This takes a boot sector and merges in the syslinux fields */
+void syslinux_make_bootsect(void *);
+
+/* Check to see that what we got was indeed an MS-DOS boot sector/superblock */
+const char *syslinux_check_bootsect(const void *bs);
+
+/* This patches the boot sector and ldlinux.sys based on a sector map */
+typedef uint64_t sector_t;
+int syslinux_patch(const sector_t *sectors, int nsectors,
+ int stupid, int raid_mode,
+ const char *subdir, const char *subvol);
+
+#endif
diff --git a/contrib/syslinux-4.02/libinstaller/syslxcom.c b/contrib/syslinux-4.02/libinstaller/syslxcom.c
new file mode 100644
index 0000000..b176f6d
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslxcom.c
@@ -0,0 +1,286 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corp. - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslxcom.c
+ *
+ * common functions for extlinux & syslinux installer
+ *
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/vfs.h>
+#include "linuxioctl.h"
+#include "syslxcom.h"
+
+const char *program;
+
+int fs_type;
+
+#ifdef DEBUG
+# define dprintf printf
+#else
+# define dprintf(...) ((void)0)
+#endif
+
+#define SECTOR_SHIFT 9
+
+static void die(const char *msg)
+{
+ fputs(msg, stderr);
+ exit(1);
+}
+
+/*
+ * read/write wrapper functions
+ */
+ssize_t xpread(int fd, void *buf, size_t count, off_t offset)
+{
+ char *bufp = (char *)buf;
+ ssize_t rv;
+ ssize_t done = 0;
+
+ while (count) {
+ rv = pread(fd, bufp, count, offset);
+ if (rv == 0) {
+ die("short read");
+ } else if (rv == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ die(strerror(errno));
+ }
+ } else {
+ bufp += rv;
+ offset += rv;
+ done += rv;
+ count -= rv;
+ }
+ }
+
+ return done;
+}
+
+ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ const char *bufp = (const char *)buf;
+ ssize_t rv;
+ ssize_t done = 0;
+
+ while (count) {
+ rv = pwrite(fd, bufp, count, offset);
+ if (rv == 0) {
+ die("short write");
+ } else if (rv == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ die(strerror(errno));
+ }
+ } else {
+ bufp += rv;
+ offset += rv;
+ done += rv;
+ count -= rv;
+ }
+ }
+
+ return done;
+}
+
+/*
+ * Set and clear file attributes
+ */
+void clear_attributes(int fd)
+{
+ struct stat st;
+
+ if (!fstat(fd, &st)) {
+ switch (fs_type) {
+ case EXT2:
+ {
+ int flags;
+
+ if (!ioctl(fd, EXT2_IOC_GETFLAGS, &flags)) {
+ flags &= ~EXT2_IMMUTABLE_FL;
+ ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+ }
+ break;
+ }
+ case VFAT:
+ {
+ uint32_t attr = 0x00; /* Clear all attributes */
+ ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
+ break;
+ }
+ default:
+ break;
+ }
+ fchmod(fd, st.st_mode | S_IWUSR);
+ }
+}
+
+void set_attributes(int fd)
+{
+ struct stat st;
+
+ if (!fstat(fd, &st)) {
+ fchmod(fd, st.st_mode & (S_IRUSR | S_IRGRP | S_IROTH));
+ switch (fs_type) {
+ case EXT2:
+ {
+ int flags;
+
+ if (st.st_uid == 0 && !ioctl(fd, EXT2_IOC_GETFLAGS, &flags)) {
+ flags |= EXT2_IMMUTABLE_FL;
+ ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+ }
+ break;
+ }
+ case VFAT:
+ {
+ uint32_t attr = 0x07; /* Hidden+System+Readonly */
+ ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+/* New FIEMAP based mapping */
+static int sectmap_fie(int fd, sector_t *sectors, int nsectors)
+{
+ struct fiemap *fm;
+ struct fiemap_extent *fe;
+ unsigned int i, nsec;
+ sector_t sec, *secp, *esec;
+ struct stat st;
+ uint64_t maplen;
+
+ if (fstat(fd, &st))
+ return -1;
+
+ fm = alloca(sizeof(struct fiemap)
+ + nsectors * sizeof(struct fiemap_extent));
+
+ memset(fm, 0, sizeof *fm);
+
+ maplen = (uint64_t)nsectors << SECTOR_SHIFT;
+ if (maplen > (uint64_t)st.st_size)
+ maplen = st.st_size;
+
+ fm->fm_start = 0;
+ fm->fm_length = maplen;
+ fm->fm_flags = FIEMAP_FLAG_SYNC;
+ fm->fm_extent_count = nsectors;
+
+ if (ioctl(fd, FS_IOC_FIEMAP, fm))
+ return -1;
+
+ memset(sectors, 0, nsectors * sizeof *sectors);
+ esec = sectors + nsectors;
+
+ fe = fm->fm_extents;
+
+ if (fm->fm_mapped_extents < 1 ||
+ !(fe[fm->fm_mapped_extents-1].fe_flags & FIEMAP_EXTENT_LAST))
+ return -1;
+
+ for (i = 0; i < fm->fm_mapped_extents; i++) {
+ if (fe->fe_flags & FIEMAP_EXTENT_LAST) {
+ /* If this is the *final* extent, pad the length */
+ fe->fe_length = (fe->fe_length + SECTOR_SIZE - 1)
+ & ~(SECTOR_SIZE - 1);
+ }
+
+ if ((fe->fe_logical | fe->fe_physical| fe->fe_length) &
+ (SECTOR_SIZE - 1))
+ return -1;
+
+ if (fe->fe_flags & (FIEMAP_EXTENT_UNKNOWN|
+ FIEMAP_EXTENT_DELALLOC|
+ FIEMAP_EXTENT_ENCODED|
+ FIEMAP_EXTENT_DATA_ENCRYPTED|
+ FIEMAP_EXTENT_UNWRITTEN))
+ return -1;
+
+ secp = sectors + (fe->fe_logical >> SECTOR_SHIFT);
+ sec = fe->fe_physical >> SECTOR_SHIFT;
+ nsec = fe->fe_length >> SECTOR_SHIFT;
+
+ while (nsec--) {
+ if (secp >= esec)
+ break;
+ *secp++ = sec++;
+ }
+
+ fe++;
+ }
+
+ return 0;
+}
+
+/* Legacy FIBMAP based mapping */
+static int sectmap_fib(int fd, sector_t *sectors, int nsectors)
+{
+ unsigned int blk, nblk;
+ unsigned int i;
+ unsigned int blksize;
+ sector_t sec;
+
+ /* Get block size */
+ if (ioctl(fd, FIGETBSZ, &blksize))
+ return -1;
+
+ /* Number of sectors per block */
+ blksize >>= SECTOR_SHIFT;
+
+ nblk = 0;
+ while (nsectors) {
+ blk = nblk++;
+ if (ioctl(fd, FIBMAP, &blk))
+ return -1;
+
+ sec = (sector_t)blk * blksize;
+ for (i = 0; i < blksize; i++) {
+ *sectors++ = sec++;
+ if (! --nsectors)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Produce file map
+ */
+int sectmap(int fd, sector_t *sectors, int nsectors)
+{
+ if (!sectmap_fie(fd, sectors, nsectors))
+ return 0;
+
+ return sectmap_fib(fd, sectors, nsectors);
+}
diff --git a/contrib/syslinux-4.02/libinstaller/syslxcom.h b/contrib/syslinux-4.02/libinstaller/syslxcom.h
new file mode 100644
index 0000000..39ca09d
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslxcom.h
@@ -0,0 +1,22 @@
+#ifndef _H_SYSLXCOM_
+#define _H_SYSLXCOM_
+
+#include "syslinux.h"
+
+/* Global fs_type for handling fat, ext2/3/4 and btrfs */
+enum filesystem {
+ NONE,
+ EXT2,
+ BTRFS,
+ VFAT,
+};
+
+extern int fs_type;
+extern const char *program;
+ssize_t xpread(int fd, void *buf, size_t count, off_t offset);
+ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset);
+void clear_attributes(int fd);
+void set_attributes(int fd);
+int sectmap(int fd, sector_t *sectors, int nsectors);
+
+#endif
diff --git a/contrib/syslinux-4.02/libinstaller/syslxint.h b/contrib/syslinux-4.02/libinstaller/syslxint.h
new file mode 100644
index 0000000..14a7fc2
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslxint.h
@@ -0,0 +1,246 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef SYSLXINT_H
+#define SYSLXINT_H
+
+#include "syslinux.h"
+
+#if defined(__386__) || defined(__i386__) || defined(__x86_64__)
+# define X86_MEM 1 /* Littleendian and unaligned safe */
+#else
+# define X86_MEM 0
+#endif
+
+/*
+ * Access functions for littleendian numbers, possibly misaligned.
+ */
+static inline uint8_t get_8(const uint8_t * p)
+{
+ return *p;
+}
+
+static inline uint16_t get_16(const uint16_t * p)
+{
+#if X86_MEM
+ /* Littleendian and unaligned-capable */
+ return *p;
+#else
+ const uint8_t *pp = (const uint8_t *)p;
+ return pp[0] + ((uint16_t)pp[1] << 8);
+#endif
+}
+
+static inline uint32_t get_32(const uint32_t * p)
+{
+#if X86_MEM
+ /* Littleendian and unaligned-capable */
+ return *p;
+#else
+ const uint16_t *pp = (const uint16_t *)p;
+ return get_16(pp[0]) + (uint32_t)get_16(pp[1]);
+#endif
+}
+
+static inline uint64_t get_64(const uint64_t * p)
+{
+#if X86_MEM
+ /* Littleendian and unaligned-capable */
+ return *p;
+#else
+ const uint32_t *pp = (const uint32_t *)p;
+ return get_32(pp[0]) + (uint64_t)get_32(pp[1]);
+#endif
+}
+
+static inline void set_8(uint8_t *p, uint8_t v)
+{
+ *p = v;
+}
+
+static inline void set_16(uint16_t *p, uint16_t v)
+{
+#if X86_MEM
+ /* Littleendian and unaligned-capable */
+ *p = v;
+#else
+ uint8_t *pp = (uint8_t *) p;
+ pp[0] = (v & 0xff);
+ pp[1] = ((v >> 8) & 0xff);
+#endif
+}
+
+static inline void set_32(uint32_t *p, uint32_t v)
+{
+#if X86_MEM
+ /* Littleendian and unaligned-capable */
+ *p = v;
+#else
+ uint8_t *pp = (uint8_t *) p;
+ pp[0] = (v & 0xff);
+ pp[1] = ((v >> 8) & 0xff);
+ pp[2] = ((v >> 16) & 0xff);
+ pp[3] = ((v >> 24) & 0xff);
+#endif
+}
+
+static inline void set_64(uint64_t *p, uint64_t v)
+{
+#if X86_MEM
+ /* Littleendian and unaligned-capable */
+ *p = v;
+#else
+ uint32_t *pp = (uint32_t *) p;
+ set_32(pp[0], v);
+ set_32(pp[1], v >> 32);
+#endif
+}
+
+/*
+ * Special handling for the MS-DOS derivative: syslinux_ldlinux
+ * is a "far" object...
+ */
+#ifdef __MSDOS__
+
+static inline __attribute__ ((const))
+uint16_t ds(void)
+{
+ uint16_t v;
+ asm("movw %%ds,%0":"=rm"(v));
+ return v;
+}
+
+static inline void *set_fs(const void *p)
+{
+ uint16_t seg;
+
+ seg = ds() + ((size_t) p >> 4);
+ asm volatile ("movw %0,%%fs"::"rm" (seg));
+ return (void *)((size_t) p & 0xf);
+}
+
+uint8_t get_8_sl(const uint8_t * p);
+uint16_t get_16_sl(const uint16_t * p);
+uint32_t get_32_sl(const uint32_t * p);
+uint64_t get_64_sl(const uint64_t * p);
+void set_8_sl(uint8_t * p, uint8_t v);
+void set_16_sl(uint16_t * p, uint16_t v);
+void set_32_sl(uint32_t * p, uint32_t v);
+void set_64_sl(uint64_t * p, uint64_t v);
+void memcpy_to_sl(void *dst, const void *src, size_t len);
+void memcpy_from_sl(void *dst, const void *src, size_t len);
+
+#else
+
+/* Sane system ... */
+#define get_8_sl(x) get_8(x)
+#define get_16_sl(x) get_16(x)
+#define get_32_sl(x) get_32(x)
+#define get_64_sl(x) get_64(x)
+#define set_8_sl(x,y) set_8(x,y)
+#define set_16_sl(x,y) set_16(x,y)
+#define set_32_sl(x,y) set_32(x,y)
+#define set_64_sl(x,y) set_64(x,y)
+#define memcpy_to_sl(d,s,l) memcpy(d,s,l)
+#define memcpy_from_sl(d,s,l) memcpy(d,s,l)
+
+#endif
+
+#define LDLINUX_MAGIC 0x3eb202fe
+
+/* Patch area for disk-based installers */
+struct patch_area {
+ uint32_t magic; /* LDLINUX_MAGIC */
+ uint32_t instance; /* Per-version value */
+ uint16_t data_sectors;
+ uint16_t adv_sectors;
+ uint32_t dwords;
+ uint32_t checksum;
+ uint16_t maxtransfer;
+ uint16_t epaoffset; /* Pointer to the extended patch area */
+};
+
+struct ext_patch_area {
+ uint16_t advptroffset; /* ADV pointers */
+ uint16_t diroffset; /* Current directory field */
+ uint16_t dirlen; /* Length of current directory field */
+ uint16_t subvoloffset; /* Subvolume field */
+ uint16_t subvollen; /* Length of subvolume field */
+ uint16_t secptroffset; /* Sector extent pointers */
+ uint16_t secptrcnt; /* Number of sector extent pointers */
+
+ uint16_t sect1ptr0; /* Boot sector offset of sector 1 ptr LSW */
+ uint16_t sect1ptr1; /* Boot sector offset of sector 1 ptr MSW */
+ uint16_t raidpatch; /* Boot sector RAID mode patch pointer */
+};
+
+/* Sector extent */
+struct syslinux_extent {
+ uint64_t lba;
+ uint16_t len;
+} __attribute__((packed));
+
+/* FAT bootsector format, also used by other disk-based derivatives */
+struct boot_sector {
+ uint8_t bsJump[3];
+ char bsOemName[8];
+ uint16_t bsBytesPerSec;
+ uint8_t bsSecPerClust;
+ uint16_t bsResSectors;
+ uint8_t bsFATs;
+ uint16_t bsRootDirEnts;
+ uint16_t bsSectors;
+ uint8_t bsMedia;
+ uint16_t bsFATsecs;
+ uint16_t bsSecPerTrack;
+ uint16_t bsHeads;
+ uint32_t bsHiddenSecs;
+ uint32_t bsHugeSectors;
+
+ union {
+ struct {
+ uint8_t DriveNumber;
+ uint8_t Reserved1;
+ uint8_t BootSignature;
+ uint32_t VolumeID;
+ char VolumeLabel[11];
+ char FileSysType[8];
+ uint8_t Code[448];
+ } __attribute__ ((packed)) bs16;
+ struct {
+ uint32_t FATSz32;
+ uint16_t ExtFlags;
+ uint16_t FSVer;
+ uint32_t RootClus;
+ uint16_t FSInfo;
+ uint16_t BkBootSec;
+ uint8_t Reserved0[12];
+ uint8_t DriveNumber;
+ uint8_t Reserved1;
+ uint8_t BootSignature;
+ uint32_t VolumeID;
+ char VolumeLabel[11];
+ char FileSysType[8];
+ uint8_t Code[420];
+ } __attribute__ ((packed)) bs32;
+ } __attribute__ ((packed));
+
+ uint16_t bsSignature;
+} __attribute__ ((packed));
+
+#define bsHead bsJump
+#define bsHeadLen offsetof(struct boot_sector, bsBytesPerSec)
+#define bsCode bs32.Code /* The common safe choice */
+#define bsCodeLen (offsetof(struct boot_sector, bsSignature) - \
+ offsetof(struct boot_sector, bsCode))
+
+#endif /* SYSLXINT_H */
diff --git a/contrib/syslinux-4.02/libinstaller/syslxmod.c b/contrib/syslinux-4.02/libinstaller/syslxmod.c
new file mode 100644
index 0000000..a68f19f
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslxmod.c
@@ -0,0 +1,197 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009-2010 Intel Corporation; author H. Peter Anvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslxmod.c - Code to provide a SYSLINUX code set to an installer.
+ */
+
+#define _XOPEN_SOURCE 500 /* Required on glibc 2.x */
+#define _BSD_SOURCE
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "syslinux.h"
+#include "syslxint.h"
+
+
+/*
+ * Generate sector extents
+ */
+static void generate_extents(struct syslinux_extent *ex, int nptrs,
+ const sector_t *sectp, int nsect)
+{
+ uint32_t addr = 0x7c00 + 2*SECTOR_SIZE;
+ uint32_t base;
+ sector_t sect, lba;
+ unsigned int len;
+
+ len = lba = base = 0;
+
+ memset(ex, 0, nptrs * sizeof *ex);
+
+ while (nsect) {
+ sect = *sectp++;
+
+ if (len && sect == lba + len &&
+ ((addr ^ (base + len * SECTOR_SIZE)) & 0xffff0000) == 0) {
+ /* We can add to the current extent */
+ len++;
+ goto next;
+ }
+
+ if (len) {
+ set_64_sl(&ex->lba, lba);
+ set_16_sl(&ex->len, len);
+ ex++;
+ }
+
+ base = addr;
+ lba = sect;
+ len = 1;
+
+ next:
+ addr += SECTOR_SIZE;
+ nsect--;
+ }
+
+ if (len) {
+ set_64_sl(&ex->lba, lba);
+ set_16_sl(&ex->len, len);
+ ex++;
+ }
+}
+
+/*
+ * Form a pointer based on a 16-bit patcharea/epa field
+ */
+static inline void *ptr(void *img, uint16_t *offset_p)
+{
+ return (char *)img + get_16_sl(offset_p);
+}
+
+/*
+ * This patches the boot sector and the beginning of ldlinux.sys
+ * based on an ldlinux.sys sector map passed in. Typically this is
+ * handled by writing ldlinux.sys, mapping it, and then overwrite it
+ * with the patched version. If this isn't safe to do because of
+ * an OS which does block reallocation, then overwrite it with
+ * direct access since the location is known.
+ *
+ * Returns the number of modified bytes in ldlinux.sys if successful,
+ * otherwise -1.
+ */
+#define NADV 2
+
+int syslinux_patch(const sector_t *sectp, int nsectors,
+ int stupid, int raid_mode,
+ const char *subdir, const char *subvol)
+{
+ struct patch_area *patcharea;
+ struct ext_patch_area *epa;
+ struct syslinux_extent *ex;
+ uint32_t *wp;
+ int nsect = ((boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT) + 2;
+ uint32_t csum;
+ int i, dw, nptrs;
+ struct boot_sector *sbs = (struct boot_sector *)boot_sector;
+ uint64_t *advptrs;
+
+ if (nsectors < nsect)
+ return -1; /* The actual file is too small for content */
+
+ /* Search for LDLINUX_MAGIC to find the patch area */
+ for (wp = (uint32_t *)boot_image; get_32_sl(wp) != LDLINUX_MAGIC;
+ wp++)
+ ;
+ patcharea = (struct patch_area *)wp;
+ epa = ptr(boot_image, &patcharea->epaoffset);
+
+ /* First sector need pointer in boot sector */
+ set_32(ptr(sbs, &epa->sect1ptr0), sectp[0]);
+ set_32(ptr(sbs, &epa->sect1ptr1), sectp[0] >> 32);
+ sectp++;
+
+ /* Handle RAID mode */
+ if (raid_mode) {
+ /* Patch in INT 18h = CD 18 */
+ set_16(ptr(sbs, &epa->raidpatch), 0x18CD);
+ }
+
+ /* Set up the totals */
+ dw = boot_image_len >> 2; /* COMPLETE dwords, excluding ADV */
+ set_16_sl(&patcharea->data_sectors, nsect - 2); /* Not including ADVs */
+ set_16_sl(&patcharea->adv_sectors, 2); /* ADVs need 2 sectors */
+ set_32_sl(&patcharea->dwords, dw);
+
+ /* Handle Stupid mode */
+ if (stupid) {
+ /* Access only one sector at a time */
+ set_16_sl(&patcharea->maxtransfer, 1);
+ }
+
+ /* Set the sector extents */
+ ex = ptr(boot_image, &epa->secptroffset);
+ nptrs = get_16_sl(&epa->secptrcnt);
+
+ if (nsect > nptrs) {
+ /* Not necessarily an error in this case, but a general problem */
+ fprintf(stderr, "Insufficient extent space, build error!\n");
+ exit(1);
+ }
+
+ /* -1 for the pointer in the boot sector, -2 for the two ADVs */
+ generate_extents(ex, nptrs, sectp, nsect-1-2);
+
+ /* ADV pointers */
+ advptrs = ptr(boot_image, &epa->advptroffset);
+ set_64_sl(&advptrs[0], sectp[nsect-1-2]);
+ set_64_sl(&advptrs[1], sectp[nsect-1-1]);
+
+ /* Poke in the base directory path */
+ if (subdir) {
+ int sublen = strlen(subdir) + 1;
+ if (get_16_sl(&epa->dirlen) < sublen) {
+ fprintf(stderr, "Subdirectory path too long... aborting install!\n");
+ exit(1);
+ }
+ memcpy_to_sl(ptr(boot_image, &epa->diroffset), subdir, sublen);
+ }
+
+ /* Poke in the subvolume information */
+ if (subvol) {
+ int sublen = strlen(subvol) + 1;
+ if (get_16_sl(&epa->subvollen) < sublen) {
+ fprintf(stderr, "Subvol name too long... aborting install!\n");
+ exit(1);
+ }
+ memcpy_to_sl(ptr(boot_image, &epa->subvoloffset), subvol, sublen);
+ }
+
+ /* Now produce a checksum */
+ set_32_sl(&patcharea->checksum, 0);
+
+ csum = LDLINUX_MAGIC;
+ for (i = 0, wp = (uint32_t *)boot_image; i < dw; i++, wp++)
+ csum -= get_32_sl(wp); /* Negative checksum */
+
+ set_32_sl(&patcharea->checksum, csum);
+
+ /*
+ * Assume all bytes modified. This can be optimized at the expense
+ * of keeping track of what the highest modified address ever was.
+ */
+ return dw << 2;
+}
diff --git a/contrib/syslinux-4.02/libinstaller/syslxopt.c b/contrib/syslinux-4.02/libinstaller/syslxopt.c
new file mode 100644
index 0000000..18a6baa
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslxopt.c
@@ -0,0 +1,267 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corp. - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslxopt.c
+ *
+ * parse cmdline for extlinux and syslinux installer
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h>
+#include <sysexits.h>
+#include "../version.h"
+#include "syslxcom.h"
+#include "syslxopt.h"
+
+/* These are the options we can set their values */
+struct sys_options opt = {
+ .sectors = 0,
+ .heads = 0,
+ .raid_mode = 0,
+ .stupid_mode = 0,
+ .reset_adv = 0,
+ .set_once = NULL,
+ .update_only = -1,
+ .directory = NULL,
+ .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'}, /* DOS/Win32/mtools only */
+ {"install", 0, NULL, 'i'},
+ {"directory", 1, NULL, 'd'},
+ {"offset", 1, NULL, 't'},
+ {"update", 0, NULL, 'U'},
+ {"zipdrive", 0, NULL, 'z'},
+ {"sectors", 1, NULL, 'S'},
+ {"stupid", 0, NULL, 's'},
+ {"heads", 1, NULL, 'H'},
+ {"raid-mode", 0, NULL, 'r'},
+ {"version", 0, NULL, 'v'},
+ {"help", 0, NULL, 'h'},
+ {"once", 1, NULL, OPT_ONCE},
+ {"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:ma";
+
+void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode)
+{
+ switch (mode) {
+ case MODE_SYSLINUX:
+ /* For unmounted fs installation (syslinux) */
+ fprintf(stderr,
+ "Usage: %s [options] device\n"
+ " --offset -t Offset of the file system on the device \n"
+ " --directory -d Directory for installation target\n",
+ program);
+ break;
+
+ case MODE_EXTLINUX:
+ /* Mounted fs installation (extlinux) */
+ /* Actually extlinux can also use -d to provide a directory too... */
+ fprintf(stderr,
+ "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"
+ " --directory -d Directory for installation target\n",
+ program);
+ break;
+ }
+
+ fprintf(stderr,
+ " --install -i Install over the current bootsector\n"
+ " --update -U Update a previous EXTLINUX installation\n"
+ " --zip -z Force zipdrive geometry (-H 64 -S 32)\n"
+ " --sectors=# -S Force the number of sectors per track\n"
+ " --heads=# -H Force number of heads\n"
+ " --stupid -s Slow, safe and stupid mode\n"
+ " --raid -r Fall back to the next device on boot failure\n"
+ " --once=... %s Execute a command once upon boot\n"
+ " --clear-once -O Clear the boot-once command\n"
+ " --reset-adv Reset auxilliary data\n",
+ mode == MODE_SYSLINUX ? " " : "-o");
+ /* Have to chop this roughly in half for the DOS installer for some reason */
+ fprintf(stderr,
+ " --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"
+ " not possible for devices which are considered floppy disks,\n"
+ " which includes zipdisks and LS-120 superfloppies.\n"
+ "\n"
+ " The -z option is useful for USB devices which are considered\n"
+ " hard disks by some BIOSes and zipdrives by other BIOSes.");
+
+ exit(rv);
+}
+
+void parse_options(int argc, char *argv[], enum syslinux_mode mode)
+{
+ int o;
+
+ program = argv[0];
+ while ((o = getopt_long(argc, argv, short_options,
+ long_options, NULL)) != EOF) {
+ switch (o) {
+ case 'f':
+ opt.force = 1;
+ break;
+ case 'z':
+ opt.heads = 64;
+ opt.sectors = 32;
+ break;
+ case 'S':
+ opt.sectors = strtoul(optarg, NULL, 0);
+ if (opt.sectors < 1 || opt.sectors > 63) {
+ fprintf(stderr,
+ "%s: invalid number of sectors: %u (must be 1-63)\n",
+ program, opt.sectors);
+ exit(EX_USAGE);
+ }
+ break;
+ case 'H':
+ opt.heads = strtoul(optarg, NULL, 0);
+ if (opt.heads < 1 || opt.heads > 256) {
+ fprintf(stderr,
+ "%s: invalid number of heads: %u (must be 1-256)\n",
+ program, opt.heads);
+ exit(EX_USAGE);
+ }
+ break;
+ case 'r':
+ opt.raid_mode = 1;
+ break;
+ case 's':
+ opt.stupid_mode = 1;
+ break;
+ case 'i':
+ opt.update_only = 0;
+ break;
+ case 'u':
+ case 'U':
+ opt.update_only = 1;
+ break;
+ case 'h':
+ usage(0, mode);
+ break;
+ case 'o':
+ if (mode == MODE_SYSLINUX) {
+ fprintf(stderr, "%s: -o will change meaning in a future version, use -t or --offset\n", program);
+ goto opt_offset;
+ }
+ /* else fall through */
+ case OPT_ONCE:
+ opt.set_once = optarg;
+ break;
+ case 't':
+ opt_offset:
+ opt.offset = strtoul(optarg, NULL, 0);
+ break;
+ case 'O':
+ opt.set_once = "";
+ break;
+ case 'd':
+ opt.directory = optarg;
+ break;
+ case OPT_RESET_ADV:
+ opt.reset_adv = 1;
+ break;
+ 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
+ " H. Peter Anvin et al\n", program);
+ exit(0);
+ default:
+ fprintf(stderr, "%s: Unknown option: -%c\n", program, optopt);
+ usage(EX_USAGE, mode);
+ }
+ }
+
+ switch (mode) {
+ case MODE_SYSLINUX:
+ case MODE_SYSLINUX_DOSWIN:
+ opt.device = argv[optind++];
+ break;
+ case MODE_EXTLINUX:
+ if (!opt.directory)
+ opt.directory = argv[optind++];
+ 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 */
+}
+
+/*
+ * Make any user-specified ADV modifications in memory
+ */
+int modify_adv(void)
+{
+ int rv = 0;
+
+ if (opt.reset_adv)
+ syslinux_reset_adv(syslinux_adv);
+
+ if (opt.set_once) {
+ if (syslinux_setadv(ADV_BOOTONCE, strlen(opt.set_once), opt.set_once)) {
+ fprintf(stderr, "%s: not enough space for boot-once command\n",
+ program);
+ rv = -1;
+ }
+ }
+ if (opt.menu_save) {
+ if (syslinux_setadv(ADV_MENUSAVE, strlen(opt.menu_save), opt.menu_save)) {
+ fprintf(stderr, "%s: not enough space for menu-save label\n",
+ program);
+ rv = -1;
+ }
+ }
+
+ return rv;
+}
diff --git a/contrib/syslinux-4.02/libinstaller/syslxopt.h b/contrib/syslinux-4.02/libinstaller/syslxopt.h
new file mode 100644
index 0000000..bcbe035
--- /dev/null
+++ b/contrib/syslinux-4.02/libinstaller/syslxopt.h
@@ -0,0 +1,43 @@
+#ifndef _H_SYSLXOPT_
+#define _H_SYSLXOPT_
+
+/* These are the options we can set and their values */
+struct sys_options {
+ unsigned int sectors;
+ unsigned int heads;
+ int raid_mode;
+ int stupid_mode;
+ int reset_adv;
+ const char *set_once;
+ int update_only;
+ const char *directory;
+ 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 {
+ OPT_NONE,
+ OPT_RESET_ADV,
+ OPT_ONCE,
+};
+
+enum syslinux_mode {
+ MODE_SYSLINUX, /* Unmounted filesystem */
+ MODE_EXTLINUX,
+ MODE_SYSLINUX_DOSWIN,
+};
+
+void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode);
+void parse_options(int argc, char *argv[], enum syslinux_mode mode);
+int modify_adv(void);
+
+extern struct sys_options opt;
+extern const struct option long_options[];
+extern const char short_options[];
+
+#endif