Index: bootcd/isolinux/syslinux-6.03/libinstaller/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+# _bin.c files required by both BTARGET and ITARGET installers
+BINFILES = bootsect_bin.c ldlinux_bin.c \
+	   mbr_bin.c gptmbr_bin.c ldlinuxc32_bin.c
+
+PERL	 = perl
+
+VPATH = $(SRC)
+
+all: installer
+
+bootsect_bin.c: $(OBJ)/../core/ldlinux.bss bin2c.pl
+	$(PERL) $(SRC)/bin2c.pl syslinux_bootsect < $< > $@
+
+ldlinux_bin.c: $(OBJ)/../core/ldlinux.sys bin2c.pl
+	$(PERL) $(SRC)/bin2c.pl syslinux_ldlinux 512 < $< > $@
+
+mbr_bin.c: $(OBJ)/../mbr/mbr.bin bin2c.pl
+	$(PERL) $(SRC)/bin2c.pl syslinux_mbr < $< > $@
+
+gptmbr_bin.c: $(OBJ)/../mbr/gptmbr.bin bin2c.pl
+	$(PERL) $(SRC)/bin2c.pl syslinux_gptmbr < $< > $@
+
+installer: $(BINFILES)
+
+ldlinuxc32_bin.c: $(OBJ)/../com32/elflink/ldlinux/ldlinux.c32 bin2c.pl
+	$(PERL) $(SRC)/bin2c.pl syslinux_ldlinuxc32 < $< > $@
+
+tidy:
+	rm -f $(BINFILES)
+
+clean: tidy
+
+dist: tidy
+
+spotless: clean
+
+strip:
Index: bootcd/isolinux/syslinux-6.03/libinstaller/advconst.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/advconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/advconst.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1 @@
+../com32/include/syslinux/advconst.h
Index: bootcd/isolinux/syslinux-6.03/libinstaller/advio.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/advio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/advio.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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;
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/bin2c.pl
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/bin2c.pl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/bin2c.pl	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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;
Index: bootcd/isolinux/syslinux-6.03/libinstaller/ext2fs/ext2_fs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/ext2fs/ext2_fs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/ext2fs/ext2_fs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,856 @@
+/*
+ *  linux/include/linux/ext2_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _EXT2FS_EXT2_FS_H
+#define _EXT2FS_EXT2_FS_H
+
+#include <linux/types.h>
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT2FS_DEBUG to produce debug messages
+ */
+#undef EXT2FS_DEBUG
+
+/*
+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
+ */
+#define EXT2_PREALLOCATE
+#define EXT2_DEFAULT_PREALLOC_BLOCKS	8
+
+/*
+ * The second extended file system version
+ */
+#define EXT2FS_DATE		"95/08/09"
+#define EXT2FS_VERSION		"0.5b"
+
+/*
+ * Special inode numbers
+ */
+#define EXT2_BAD_INO		 1	/* Bad blocks inode */
+#define EXT2_ROOT_INO		 2	/* Root inode */
+#define EXT4_USR_QUOTA_INO	 3	/* User quota inode */
+#define EXT4_GRP_QUOTA_INO	 4	/* Group quota inode */
+#define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+#define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+#define EXT2_RESIZE_INO		 7	/* Reserved group descriptors inode */
+#define EXT2_JOURNAL_INO	 8	/* Journal inode */
+#define EXT2_EXCLUDE_INO	 9	/* The "exclude" inode, for snapshots */
+#define EXT4_REPLICA_INO	10	/* Used by non-upstream feature */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO	11
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC	0xEF53
+
+#ifdef __KERNEL__
+#define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb)	(sb)
+#endif
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX		65000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_LOG_SIZE		10	/* 1024 */
+#define EXT2_MAX_BLOCK_LOG_SIZE		16	/* 65536 */
+#define EXT2_MIN_BLOCK_SIZE	(1 << EXT2_MIN_BLOCK_LOG_SIZE)
+#define EXT2_MAX_BLOCK_SIZE	(1 << EXT2_MAX_BLOCK_LOG_SIZE)
+#ifdef __KERNEL__
+#define EXT2_BLOCK_SIZE(s)	((s)->s_blocksize)
+#define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+#define EXT2_ADDR_PER_BLOCK_BITS(s)	(EXT2_SB(s)->addr_per_block_bits)
+#define EXT2_INODE_SIZE(s)	(EXT2_SB(s)->s_inode_size)
+#define EXT2_FIRST_INO(s)	(EXT2_SB(s)->s_first_ino)
+#else
+#define EXT2_BLOCK_SIZE(s)	(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
+#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
+#define EXT2_FIRST_INO(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino)
+#endif
+#define EXT2_ADDR_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / sizeof(__u32))
+
+/*
+ * Macro-instructions used to manage allocation clusters
+ */
+#define EXT2_MIN_CLUSTER_LOG_SIZE	EXT2_MIN_BLOCK_LOG_SIZE
+#define EXT2_MAX_CLUSTER_LOG_SIZE	29	/* 512MB  */
+#define EXT2_MIN_CLUSTER_SIZE		EXT2_MIN_BLOCK_SIZE
+#define EXT2_MAX_CLUSTER_SIZE		(1 << EXT2_MAX_CLUSTER_LOG_SIZE)
+#define EXT2_CLUSTER_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << \
+						(s)->s_log_cluster_size)
+#define EXT2_CLUSTER_SIZE_BITS(s)	((s)->s_log_cluster_size + 10)
+
+/*
+ * Macro-instructions used to manage fragments
+ *
+ * Note: for backwards compatibility only, for the dump program.
+ * Ext2/3/4 will never support fragments....
+ */
+#define EXT2_MIN_FRAG_SIZE              EXT2_MIN_BLOCK_SIZE
+#define EXT2_MAX_FRAG_SIZE              EXT2_MAX_BLOCK_SIZE
+#define EXT2_MIN_FRAG_LOG_SIZE          EXT2_MIN_BLOCK_LOG_SIZE
+#define EXT2_FRAG_SIZE(s)		EXT2_BLOCK_SIZE(s)
+#define EXT2_FRAGS_PER_BLOCK(s)		1
+
+/*
+ * ACL structures
+ */
+struct ext2_acl_header	/* Header of Access Control Lists */
+{
+	__u32	aclh_size;
+	__u32	aclh_file_count;
+	__u32	aclh_acle_count;
+	__u32	aclh_first_acle;
+};
+
+struct ext2_acl_entry	/* Access Control List Entry */
+{
+	__u32	acle_size;
+	__u16	acle_perms;	/* Access permissions */
+	__u16	acle_type;	/* Type of entry */
+	__u16	acle_tag;	/* User or group identity */
+	__u16	acle_pad1;
+	__u32	acle_next;	/* Pointer on next entry for the */
+					/* same inode or on next free entry */
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+	__u32	bg_block_bitmap;	/* Blocks bitmap block */
+	__u32	bg_inode_bitmap;	/* Inodes bitmap block */
+	__u32	bg_inode_table;		/* Inodes table block */
+	__u16	bg_free_blocks_count;	/* Free blocks count */
+	__u16	bg_free_inodes_count;	/* Free inodes count */
+	__u16	bg_used_dirs_count;	/* Directories count */
+	__u16	bg_flags;
+	__u32	bg_exclude_bitmap_lo;	/* Exclude bitmap for snapshots */
+	__u16	bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_itable_unused;	/* Unused inodes count */
+	__u16	bg_checksum;		/* crc16(s_uuid+grouo_num+group_desc)*/
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext4_group_desc
+{
+	__u32	bg_block_bitmap;	/* Blocks bitmap block */
+	__u32	bg_inode_bitmap;	/* Inodes bitmap block */
+	__u32	bg_inode_table;		/* Inodes table block */
+	__u16	bg_free_blocks_count;	/* Free blocks count */
+	__u16	bg_free_inodes_count;	/* Free inodes count */
+	__u16	bg_used_dirs_count;	/* Directories count */
+	__u16	bg_flags;		/* EXT4_BG_flags (INODE_UNINIT, etc) */
+	__u32	bg_exclude_bitmap_lo;	/* Exclude bitmap for snapshots */
+	__u16	bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_itable_unused;	/* Unused inodes count */
+	__u16	bg_checksum;		/* crc16(sb_uuid+group+desc) */
+	__u32	bg_block_bitmap_hi;	/* Blocks bitmap block MSB */
+	__u32	bg_inode_bitmap_hi;	/* Inodes bitmap block MSB */
+	__u32	bg_inode_table_hi;	/* Inodes table block MSB */
+	__u16	bg_free_blocks_count_hi;/* Free blocks count MSB */
+	__u16	bg_free_inodes_count_hi;/* Free inodes count MSB */
+	__u16	bg_used_dirs_count_hi;	/* Directories count MSB */
+	__u16	bg_itable_unused_hi;	/* Unused inodes count MSB */
+	__u32	bg_exclude_bitmap_hi;	/* Exclude bitmap block MSB */
+	__u16	bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */
+	__u16	bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */
+	__u32	bg_reserved;
+};
+
+#define EXT2_BG_INODE_UNINIT	0x0001 /* Inode table/bitmap not initialized */
+#define EXT2_BG_BLOCK_UNINIT	0x0002 /* Block bitmap not initialized */
+#define EXT2_BG_INODE_ZEROED	0x0004 /* On-disk itable initialized to zero */
+
+/*
+ * Data structures used by the directory indexing feature
+ *
+ * Note: all of the multibyte integer fields are little endian.
+ */
+
+/*
+ * Note: dx_root_info is laid out so that if it should somehow get
+ * overlaid by a dirent the two low bits of the hash version will be
+ * zero.  Therefore, the hash version mod 4 should never be 0.
+ * Sincerely, the paranoia department.
+ */
+struct ext2_dx_root_info {
+	__u32 reserved_zero;
+	__u8 hash_version; /* 0 now, 1 at release */
+	__u8 info_length; /* 8 */
+	__u8 indirect_levels;
+	__u8 unused_flags;
+};
+
+#define EXT2_HASH_LEGACY		0
+#define EXT2_HASH_HALF_MD4		1
+#define EXT2_HASH_TEA			2
+#define EXT2_HASH_LEGACY_UNSIGNED	3 /* reserved for userspace lib */
+#define EXT2_HASH_HALF_MD4_UNSIGNED	4 /* reserved for userspace lib */
+#define EXT2_HASH_TEA_UNSIGNED		5 /* reserved for userspace lib */
+
+#define EXT2_HASH_FLAG_INCOMPAT	0x1
+
+struct ext2_dx_entry {
+	__u32 hash;
+	__u32 block;
+};
+
+struct ext2_dx_countlimit {
+	__u16 limit;
+	__u16 count;
+};
+
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#define EXT2_MIN_DESC_SIZE             32
+#define EXT2_MIN_DESC_SIZE_64BIT       64
+#define EXT2_MAX_DESC_SIZE             EXT2_MIN_BLOCK_SIZE
+#define EXT2_DESC_SIZE(s)                                                \
+       ((EXT2_SB(s)->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) ? \
+	(s)->s_desc_size : EXT2_MIN_DESC_SIZE)
+
+#define EXT2_BLOCKS_PER_GROUP(s)	(EXT2_SB(s)->s_blocks_per_group)
+#define EXT2_INODES_PER_GROUP(s)	(EXT2_SB(s)->s_inodes_per_group)
+#define EXT2_CLUSTERS_PER_GROUP(s)	(EXT2_SB(s)->s_clusters_per_group)
+#define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
+/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
+#define EXT2_MAX_BLOCKS_PER_GROUP(s)	((((unsigned) 1 << 16) - 8) *	\
+					 (EXT2_CLUSTER_SIZE(s) / \
+					  EXT2_BLOCK_SIZE(s)))
+#define EXT2_MAX_CLUSTERS_PER_GROUP(s)	(((unsigned) 1 << 16) - 8)
+#define EXT2_MAX_INODES_PER_GROUP(s)	(((unsigned) 1 << 16) - \
+					 EXT2_INODES_PER_BLOCK(s))
+#ifdef __KERNEL__
+#define EXT2_DESC_PER_BLOCK(s)		(EXT2_SB(s)->s_desc_per_block)
+#define EXT2_DESC_PER_BLOCK_BITS(s)	(EXT2_SB(s)->s_desc_per_block_bits)
+#else
+#define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define EXT2_NDIR_BLOCKS		12
+#define EXT2_IND_BLOCK			EXT2_NDIR_BLOCKS
+#define EXT2_DIND_BLOCK			(EXT2_IND_BLOCK + 1)
+#define EXT2_TIND_BLOCK			(EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS			(EXT2_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define EXT2_SECRM_FL			0x00000001 /* Secure deletion */
+#define EXT2_UNRM_FL			0x00000002 /* Undelete */
+#define EXT2_COMPR_FL			0x00000004 /* Compress file */
+#define EXT2_SYNC_FL			0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
+#define EXT2_NOATIME_FL			0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT2_DIRTY_FL			0x00000100
+#define EXT2_COMPRBLK_FL		0x00000200 /* One or more compressed clusters */
+#define EXT2_NOCOMPR_FL			0x00000400 /* Access raw compressed data */
+#define EXT2_ECOMPR_FL			0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT2_BTREE_FL			0x00001000 /* btree format dir */
+#define EXT2_INDEX_FL			0x00001000 /* hash-indexed directory */
+#define EXT2_IMAGIC_FL			0x00002000
+#define EXT3_JOURNAL_DATA_FL		0x00004000 /* file data should be journaled */
+#define EXT2_NOTAIL_FL			0x00008000 /* file tail should not be merged */
+#define EXT2_DIRSYNC_FL 		0x00010000 /* Synchronous directory modifications */
+#define EXT2_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
+#define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
+#define EXT4_EXTENTS_FL 		0x00080000 /* Inode uses extents */
+#define EXT4_EA_INODE_FL	        0x00200000 /* Inode used for large EA */
+/* EXT4_EOFBLOCKS_FL 0x00400000 was here */
+#define EXT4_SNAPFILE_FL		0x01000000  /* Inode is a snapshot */
+#define EXT4_SNAPFILE_DELETED_FL	0x04000000  /* Snapshot is being deleted */
+#define EXT4_SNAPFILE_SHRUNK_FL		0x08000000  /* Snapshot shrink has completed */
+#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE		0x004BDFFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE		0x004B80FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+
+/* Used for online resize */
+struct ext2_new_group_input {
+	__u32 group;		/* Group number for this data */
+	__u32 block_bitmap;	/* Absolute block number of block bitmap */
+	__u32 inode_bitmap;	/* Absolute block number of inode bitmap */
+	__u32 inode_table;	/* Absolute block number of inode table start */
+	__u32 blocks_count;	/* Total number of blocks in this group */
+	__u16 reserved_blocks;	/* Number of reserved blocks in this group */
+	__u16 unused;		/* Number of reserved GDT blocks in group */
+};
+
+struct ext4_new_group_input {
+	__u32 group;		/* Group number for this data */
+	__u64 block_bitmap;	/* Absolute block number of block bitmap */
+	__u64 inode_bitmap;	/* Absolute block number of inode bitmap */
+	__u64 inode_table;	/* Absolute block number of inode table start */
+	__u32 blocks_count;	/* Total number of blocks in this group */
+	__u16 reserved_blocks;	/* Number of reserved blocks in this group */
+	__u16 unused;
+};
+
+#ifdef __GNU__			/* Needed for the Hurd */
+#define _IOT_ext2_new_group_input _IOT (_IOTS(__u32), 5, _IOTS(__u16), 2, 0, 0)
+#endif
+
+#define EXT2_IOC_GETFLAGS		_IOR('f', 1, long)
+#define EXT2_IOC_SETFLAGS		_IOW('f', 2, long)
+#define EXT2_IOC_GETVERSION		_IOR('v', 1, long)
+#define EXT2_IOC_SETVERSION		_IOW('v', 2, long)
+#define EXT2_IOC_GETVERSION_NEW		_IOR('f', 3, long)
+#define EXT2_IOC_SETVERSION_NEW		_IOW('f', 4, long)
+#define EXT2_IOC_GROUP_EXTEND		_IOW('f', 7, unsigned long)
+#define EXT2_IOC_GROUP_ADD		_IOW('f', 8,struct ext2_new_group_input)
+#define EXT4_IOC_GROUP_ADD		_IOW('f', 8,struct ext4_new_group_input)
+#define EXT4_IOC_RESIZE_FS		_IOW('f', 16, __u64)
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+	__u16	i_mode;		/* File mode */
+	__u16	i_uid;		/* Low 16 bits of Owner Uid */
+	__u32	i_size;		/* Size in bytes */
+	__u32	i_atime;	/* Access time */
+	__u32	i_ctime;	/* Inode change time */
+	__u32	i_mtime;	/* Modification time */
+	__u32	i_dtime;	/* Deletion Time */
+	__u16	i_gid;		/* Low 16 bits of Group Id */
+	__u16	i_links_count;	/* Links count */
+	__u32	i_blocks;	/* Blocks count */
+	__u32	i_flags;	/* File flags */
+	union {
+		struct {
+			__u32	l_i_version; /* was l_i_reserved1 */
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+	} osd1;				/* OS dependent 1 */
+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+	__u32	i_generation;	/* File version (for NFS) */
+	__u32	i_file_acl;	/* File ACL */
+	__u32	i_size_high;	/* Formerly i_dir_acl, directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u16	l_i_blocks_hi;
+			__u16	l_i_file_acl_high;
+			__u16	l_i_uid_high;	/* these 2 fields    */
+			__u16	l_i_gid_high;	/* were reserved2[0] */
+			__u16	l_i_checksum_lo; /* crc32c(uuid+inum+inode) */
+			__u16	l_i_reserved;
+		} linux2;
+		struct {
+			__u8	h_i_frag;	/* Fragment number */
+			__u8	h_i_fsize;	/* Fragment size */
+			__u16	h_i_mode_high;
+			__u16	h_i_uid_high;
+			__u16	h_i_gid_high;
+			__u32	h_i_author;
+		} hurd2;
+	} osd2;				/* OS dependent 2 */
+};
+
+/*
+ * Permanent part of an large inode on the disk
+ */
+struct ext2_inode_large {
+	__u16	i_mode;		/* File mode */
+	__u16	i_uid;		/* Low 16 bits of Owner Uid */
+	__u32	i_size;		/* Size in bytes */
+	__u32	i_atime;	/* Access time */
+	__u32	i_ctime;	/* Inode Change time */
+	__u32	i_mtime;	/* Modification time */
+	__u32	i_dtime;	/* Deletion Time */
+	__u16	i_gid;		/* Low 16 bits of Group Id */
+	__u16	i_links_count;	/* Links count */
+	__u32	i_blocks;	/* Blocks count */
+	__u32	i_flags;	/* File flags */
+	union {
+		struct {
+			__u32	l_i_version; /* was l_i_reserved1 */
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+	} osd1;				/* OS dependent 1 */
+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+	__u32	i_generation;	/* File version (for NFS) */
+	__u32	i_file_acl;	/* File ACL */
+	__u32	i_size_high;	/* Formerly i_dir_acl, directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u16	l_i_blocks_hi;
+			__u16	l_i_file_acl_high;
+			__u16	l_i_uid_high;	/* these 2 fields    */
+			__u16	l_i_gid_high;	/* were reserved2[0] */
+			__u16	l_i_checksum_lo; /* crc32c(uuid+inum+inode) */
+			__u16	l_i_reserved;
+		} linux2;
+		struct {
+			__u8	h_i_frag;	/* Fragment number */
+			__u8	h_i_fsize;	/* Fragment size */
+			__u16	h_i_mode_high;
+			__u16	h_i_uid_high;
+			__u16	h_i_gid_high;
+			__u32	h_i_author;
+		} hurd2;
+	} osd2;				/* OS dependent 2 */
+	__u16	i_extra_isize;
+	__u16	i_checksum_hi;	/* crc32c(uuid+inum+inode) */
+	__u32	i_ctime_extra;	/* extra Change time (nsec << 2 | epoch) */
+	__u32	i_mtime_extra;	/* extra Modification time (nsec << 2 | epoch) */
+	__u32	i_atime_extra;	/* extra Access time (nsec << 2 | epoch) */
+	__u32	i_crtime;	/* File creation time */
+	__u32	i_crtime_extra;	/* extra File creation time (nsec << 2 | epoch)*/
+	__u32	i_version_hi;	/* high 32 bits for 64-bit version */
+};
+
+#define i_dir_acl	i_size_high
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1	osd1.linux1.l_i_reserved1
+#define i_frag		osd2.linux2.l_i_frag
+#define i_fsize		osd2.linux2.l_i_fsize
+#define i_uid_low	i_uid
+#define i_gid_low	i_gid
+#define i_uid_high	osd2.linux2.l_i_uid_high
+#define i_gid_high	osd2.linux2.l_i_gid_high
+#else
+#if defined(__GNU__)
+
+#define i_translator	osd1.hurd1.h_i_translator
+#define i_frag		osd2.hurd2.h_i_frag;
+#define i_fsize		osd2.hurd2.h_i_fsize;
+#define i_uid_high	osd2.hurd2.h_i_uid_high
+#define i_gid_high	osd2.hurd2.h_i_gid_high
+#define i_author	osd2.hurd2.h_i_author
+
+#endif  /* __GNU__ */
+#endif	/* defined(__KERNEL__) || defined(__linux__) */
+
+#define inode_uid(inode)	((inode).i_uid | (inode).osd2.linux2.l_i_uid_high << 16)
+#define inode_gid(inode)	((inode).i_gid | (inode).osd2.linux2.l_i_gid_high << 16)
+#define ext2fs_set_i_uid_high(inode,x) ((inode).osd2.linux2.l_i_uid_high = (x))
+#define ext2fs_set_i_gid_high(inode,x) ((inode).osd2.linux2.l_i_gid_high = (x))
+
+/*
+ * File system states
+ */
+#define EXT2_VALID_FS			0x0001	/* Unmounted cleanly */
+#define EXT2_ERROR_FS			0x0002	/* Errors detected */
+#define EXT3_ORPHAN_FS			0x0004	/* Orphans being recovered */
+
+/*
+ * Misc. filesystem flags
+ */
+#define EXT2_FLAGS_SIGNED_HASH		0x0001  /* Signed dirhash in use */
+#define EXT2_FLAGS_UNSIGNED_HASH	0x0002  /* Unsigned dirhash in use */
+#define EXT2_FLAGS_TEST_FILESYS		0x0004	/* OK for use on development code */
+#define EXT2_FLAGS_IS_SNAPSHOT		0x0010	/* This is a snapshot image */
+#define EXT2_FLAGS_FIX_SNAPSHOT		0x0020	/* Snapshot inodes corrupted */
+#define EXT2_FLAGS_FIX_EXCLUDE		0x0040	/* Exclude bitmaps corrupted */
+
+/*
+ * Mount flags
+ */
+#define EXT2_MOUNT_CHECK		0x0001	/* Do mount-time checks */
+#define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO		0x0020	/* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+#define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
+
+#define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt)		(EXT2_SB(sb)->s_mount_opt & \
+					 EXT2_MOUNT_##opt)
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT2_DFL_MAX_MNT_COUNT		20	/* Allow 20 mounts */
+#define EXT2_DFL_CHECKINTERVAL		0	/* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT2_ERRORS_CONTINUE		1	/* Continue execution */
+#define EXT2_ERRORS_RO			2	/* Remount fs read-only */
+#define EXT2_ERRORS_PANIC		3	/* Panic */
+#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE
+
+#if (__GNUC__ >= 4)
+#define ext4_offsetof(TYPE,MEMBER) __builtin_offsetof(TYPE,MEMBER)
+#else
+#define ext4_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+	__u32	s_inodes_count;		/* Inodes count */
+	__u32	s_blocks_count;		/* Blocks count */
+	__u32	s_r_blocks_count;	/* Reserved blocks count */
+	__u32	s_free_blocks_count;	/* Free blocks count */
+	__u32	s_free_inodes_count;	/* Free inodes count */
+	__u32	s_first_data_block;	/* First Data Block */
+	__u32	s_log_block_size;	/* Block size */
+	__u32	s_log_cluster_size;	/* Allocation cluster size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_clusters_per_group;	/* # Fragments per group */
+	__u32	s_inodes_per_group;	/* # Inodes per group */
+	__u32	s_mtime;		/* Mount time */
+	__u32	s_wtime;		/* Write time */
+	__u16	s_mnt_count;		/* Mount count */
+	__s16	s_max_mnt_count;	/* Maximal mount count */
+	__u16	s_magic;		/* Magic signature */
+	__u16	s_state;		/* File system state */
+	__u16	s_errors;		/* Behaviour when detecting errors */
+	__u16	s_minor_rev_level;	/* minor revision level */
+	__u32	s_lastcheck;		/* time of last check */
+	__u32	s_checkinterval;	/* max. time between checks */
+	__u32	s_creator_os;		/* OS */
+	__u32	s_rev_level;		/* Revision level */
+	__u16	s_def_resuid;		/* Default uid for reserved blocks */
+	__u16	s_def_resgid;		/* Default gid for reserved blocks */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 *
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino;		/* First non-reserved inode */
+	__u16   s_inode_size;		/* size of inode structure */
+	__u16	s_block_group_nr;	/* block group # of this superblock */
+	__u32	s_feature_compat;	/* compatible feature set */
+	__u32	s_feature_incompat;	/* incompatible feature set */
+	__u32	s_feature_ro_compat;	/* readonly-compatible feature set */
+	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	char	s_volume_name[16];	/* volume name */
+	char	s_last_mounted[64];	/* directory where last mounted */
+	__u32	s_algorithm_usage_bitmap; /* For compression */
+	/*
+	 * Performance hints.  Directory preallocation should only
+	 * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
+	 */
+	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
+	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
+	__u16	s_reserved_gdt_blocks;	/* Per group table for online growth */
+	/*
+	 * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
+	 */
+	__u8	s_journal_uuid[16];	/* uuid of journal superblock */
+	__u32	s_journal_inum;		/* inode number of journal file */
+	__u32	s_journal_dev;		/* device number of journal file */
+	__u32	s_last_orphan;		/* start of list of inodes to delete */
+	__u32	s_hash_seed[4];		/* HTREE hash seed */
+	__u8	s_def_hash_version;	/* Default hash version to use */
+	__u8	s_jnl_backup_type; 	/* Default type of journal backup */
+	__u16	s_desc_size;		/* Group desc. size: INCOMPAT_64BIT */
+	__u32	s_default_mount_opts;
+	__u32	s_first_meta_bg;	/* First metablock group */
+	__u32	s_mkfs_time;		/* When the filesystem was created */
+	__u32	s_jnl_blocks[17]; 	/* Backup of the journal inode */
+	__u32	s_blocks_count_hi;	/* Blocks count high 32bits */
+	__u32	s_r_blocks_count_hi;	/* Reserved blocks count high 32 bits*/
+	__u32	s_free_blocks_hi; 	/* Free blocks count */
+	__u16	s_min_extra_isize;	/* All inodes have at least # bytes */
+	__u16	s_want_extra_isize; 	/* New inodes should reserve # bytes */
+	__u32	s_flags;		/* Miscellaneous flags */
+	__u16   s_raid_stride;		/* RAID stride */
+	__u16   s_mmp_update_interval;  /* # seconds to wait in MMP checking */
+	__u64   s_mmp_block;            /* Block for multi-mount protection */
+	__u32   s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+	__u8	s_log_groups_per_flex;	/* FLEX_BG group size */
+	__u8    s_reserved_char_pad;
+	__u16	s_reserved_pad;		/* Padding to next 32bits */
+	__u64	s_kbytes_written;	/* nr of lifetime kilobytes written */
+	__u32	s_snapshot_inum;	/* Inode number of active snapshot */
+	__u32	s_snapshot_id;		/* sequential ID of active snapshot */
+	__u64	s_snapshot_r_blocks_count; /* reserved blocks for active
+					      snapshot's future use */
+	__u32	s_snapshot_list;	/* inode number of the head of the on-disk snapshot list */
+#define EXT4_S_ERR_START ext4_offsetof(struct ext2_super_block, s_error_count)
+	__u32	s_error_count;		/* number of fs errors */
+	__u32	s_first_error_time;	/* first time an error happened */
+	__u32	s_first_error_ino;	/* inode involved in first error */
+	__u64	s_first_error_block;	/* block involved of first error */
+	__u8	s_first_error_func[32];	/* function where the error happened */
+	__u32	s_first_error_line;	/* line number where error happened */
+	__u32	s_last_error_time;	/* most recent time of an error */
+	__u32	s_last_error_ino;	/* inode involved in last error */
+	__u32	s_last_error_line;	/* line number where error happened */
+	__u64	s_last_error_block;	/* block involved of last error */
+	__u8	s_last_error_func[32];	/* function where the error happened */
+#define EXT4_S_ERR_END ext4_offsetof(struct ext2_super_block, s_mount_opts)
+	__u8	s_mount_opts[64];
+	__u32	s_usr_quota_inum;	/* inode number of user quota file */
+	__u32	s_grp_quota_inum;	/* inode number of group quota file */
+	__u32	s_overhead_blocks;	/* overhead blocks/clusters in fs */
+	__u32   s_reserved[108];        /* Padding to the end of the block */
+	__u32	s_checksum;		/* crc32c(superblock) */
+};
+
+#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX		0
+#define EXT2_OS_HURD		1
+#define EXT2_OBSO_OS_MASIX	2
+#define EXT2_OS_FREEBSD		3
+#define EXT2_OS_LITES		4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
+#define EXT2_DYNAMIC_REV	1	/* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Journal inode backup types
+ */
+#define EXT3_JNL_BACKUP_BLOCKS	1
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_compat & (mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_incompat & (mask) )
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC	0x0001
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES	0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL		0x0004
+#define EXT2_FEATURE_COMPAT_EXT_ATTR		0x0008
+#define EXT2_FEATURE_COMPAT_RESIZE_INODE	0x0010
+#define EXT2_FEATURE_COMPAT_DIR_INDEX		0x0020
+#define EXT2_FEATURE_COMPAT_LAZY_BG		0x0040
+/* #define EXT2_FEATURE_COMPAT_EXCLUDE_INODE	0x0080 not used, legacy */
+#define EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP	0x0100
+
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
+/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR	0x0004 not used */
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE	0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM		0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK	0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE	0x0040
+#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT	0x0080
+#define EXT4_FEATURE_RO_COMPAT_QUOTA		0x0100
+#define EXT4_FEATURE_RO_COMPAT_BIGALLOC		0x0200
+#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM	0x0400
+#define EXT4_FEATURE_RO_COMPAT_REPLICA		0x0800
+
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
+#define EXT2_FEATURE_INCOMPAT_META_BG		0x0010
+#define EXT3_FEATURE_INCOMPAT_EXTENTS		0x0040
+#define EXT4_FEATURE_INCOMPAT_64BIT		0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP		0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
+#define EXT4_FEATURE_INCOMPAT_EA_INODE		0x0400
+#define EXT4_FEATURE_INCOMPAT_DIRDATA		0x1000
+
+#define EXT2_FEATURE_COMPAT_SUPP	0
+#define EXT2_FEATURE_INCOMPAT_SUPP    (EXT2_FEATURE_INCOMPAT_FILETYPE| \
+				       EXT4_FEATURE_INCOMPAT_MMP)
+#define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
+					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define EXT2_DEF_RESUID		0
+#define EXT2_DEF_RESGID		0
+
+/*
+ * Default mount options
+ */
+#define EXT2_DEFM_DEBUG		0x0001
+#define EXT2_DEFM_BSDGROUPS	0x0002
+#define EXT2_DEFM_XATTR_USER	0x0004
+#define EXT2_DEFM_ACL		0x0008
+#define EXT2_DEFM_UID16		0x0010
+#define EXT3_DEFM_JMODE		0x0060
+#define EXT3_DEFM_JMODE_DATA	0x0020
+#define EXT3_DEFM_JMODE_ORDERED	0x0040
+#define EXT3_DEFM_JMODE_WBACK	0x0060
+#define EXT4_DEFM_NOBARRIER	0x0100
+#define EXT4_DEFM_BLOCK_VALIDITY 0x0200
+#define EXT4_DEFM_DISCARD	0x0400
+#define EXT4_DEFM_NODELALLOC	0x0800
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u16	name_len;		/* Name length */
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * The new version of the directory entry.  Since EXT2 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext2_dir_entry_2 {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u8	name_len;		/* Name length */
+	__u8	file_type;
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * Ext2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT2_FT_UNKNOWN		0
+#define EXT2_FT_REG_FILE	1
+#define EXT2_FT_DIR		2
+#define EXT2_FT_CHRDEV		3
+#define EXT2_FT_BLKDEV		4
+#define EXT2_FT_FIFO		5
+#define EXT2_FT_SOCK		6
+#define EXT2_FT_SYMLINK		7
+
+#define EXT2_FT_MAX		8
+
+/*
+ * EXT2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT2_DIR_PAD			4
+#define EXT2_DIR_ROUND			(EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
+					 ~EXT2_DIR_ROUND)
+
+/*
+ * This structure is used for multiple mount protection. It is written
+ * into the block number saved in the s_mmp_block field in the superblock.
+ * Programs that check MMP should assume that if SEQ_FSCK (or any unknown
+ * code above SEQ_MAX) is present then it is NOT safe to use the filesystem,
+ * regardless of how old the timestamp is.
+ *
+ * The timestamp in the MMP structure will be updated by e2fsck at some
+ * arbitary intervals (start of passes, after every few groups of inodes
+ * in pass1 and pass1b).  There is no guarantee that e2fsck is updating
+ * the MMP block in a timely manner, and the updates it does are purely
+ * for the convenience of the sysadmin and not for automatic validation.
+ *
+ * Note: Only the mmp_seq value is used to determine whether the MMP block
+ *	is being updated.  The mmp_time, mmp_nodename, and mmp_bdevname
+ *	fields are only for informational purposes for the administrator,
+ *	due to clock skew between nodes and hostname HA service takeover.
+ */
+#define EXT4_MMP_MAGIC     0x004D4D50U /* ASCII for MMP */
+#define EXT4_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */
+#define EXT4_MMP_SEQ_FSCK  0xE24D4D50U /* mmp_seq value when being fscked */
+#define EXT4_MMP_SEQ_MAX   0xE24D4D4FU /* maximum valid mmp_seq value */
+
+struct mmp_struct {
+	__u32	mmp_magic;		/* Magic number for MMP */
+	__u32	mmp_seq;		/* Sequence no. updated periodically */
+	__u64	mmp_time;		/* Time last updated */
+	char	mmp_nodename[64];	/* Node which last updated MMP block */
+	char	mmp_bdevname[32];	/* Bdev which last updated MMP block */
+	__u16	mmp_check_interval;	/* Changed mmp_check_interval */
+	__u16	mmp_pad1;
+	__u32	mmp_pad2[227];
+};
+
+/*
+ * Default interval for MMP update in seconds.
+ */
+#define EXT4_MMP_UPDATE_INTERVAL	5
+
+/*
+ * Maximum interval for MMP update in seconds.
+ */
+#define EXT4_MMP_MAX_UPDATE_INTERVAL	300
+
+/*
+ * Minimum interval for MMP checking in seconds.
+ */
+#define EXT4_MMP_MIN_CHECK_INTERVAL     5
+
+#endif	/* _EXT2FS_EXT2_FS_H */
Index: bootcd/isolinux/syslinux-6.03/libinstaller/fs.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/fs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/fs.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,174 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1998-2011 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2011 Intel Corporation; author H. Peter Anvin
+ *   Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fs.c - Generic sanity check for FAT/NTFS-based installers
+ */
+
+#define _XOPEN_SOURCE 500	/* Required on glibc 2.x */
+#define _BSD_SOURCE
+/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */
+#define _DEFAULT_SOURCE 1
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "syslinux.h"
+#include "syslxint.h"
+#include "syslxcom.h"
+#include "syslxfs.h"
+
+void syslinux_make_bootsect(void *bs, int fs_type)
+{
+    if (fs_type == VFAT) {
+	struct fat_boot_sector *bootsect = bs;
+	const struct fat_boot_sector *sbs =
+	    (const struct fat_boot_sector *)boot_sector;
+
+	memcpy(&bootsect->FAT_bsHead, &sbs->FAT_bsHead, FAT_bsHeadLen);
+	memcpy(&bootsect->FAT_bsCode, &sbs->FAT_bsCode, FAT_bsCodeLen);
+    } else if (fs_type == NTFS) {
+	struct ntfs_boot_sector *bootsect = bs;
+	const struct ntfs_boot_sector *sbs =
+	    (const struct ntfs_boot_sector *)boot_sector;
+
+	memcpy(&bootsect->NTFS_bsHead, &sbs->NTFS_bsHead, NTFS_bsHeadLen);
+	memcpy(&bootsect->NTFS_bsCode, &sbs->NTFS_bsCode, NTFS_bsCodeLen);
+    }
+}
+
+static const char *check_fat_bootsect(const void *bs, int *fs_type)
+{
+    int sectorsize;
+    const struct fat_boot_sector *sectbuf = bs;
+    long long sectors, fatsectors, dsectors;
+    long long clusters;
+    int rootdirents, clustersize;
+
+    sectorsize = get_16(&sectbuf->bsBytesPerSec);
+
+    clustersize = get_8(&sectbuf->bsSecPerClust);
+    if (clustersize == 0 || (clustersize & (clustersize - 1)))
+	return "impossible cluster size on an FAT volume";
+
+    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 on an FAT volume";
+
+    clusters = dsectors / clustersize;
+
+    fatsectors = get_16(&sectbuf->bsFATsecs);
+    fatsectors = fatsectors ? fatsectors : get_32(&sectbuf->bs32.FATSz32);
+    fatsectors *= get_8(&sectbuf->bsFATs);
+
+    if (!fatsectors)
+	return "zero FAT sectors";
+
+    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 on an FAT volume";
+    }
+
+    if (fs_type)
+	*fs_type = VFAT;
+
+    return NULL;
+}
+
+static const char *check_ntfs_bootsect(const void *bs, int *fs_type)
+{
+    const struct ntfs_boot_sector *sectbuf = bs;
+
+    if (memcmp(&sectbuf->bsOemName, "NTFS    ", 8) &&
+	memcmp(&sectbuf->bsOemName, "MSWIN4.0", 8) &&
+	memcmp(&sectbuf->bsOemName, "MSWIN4.1", 8))
+	return "unknown OEM name but claims NTFS";
+
+    if (fs_type)
+	*fs_type = NTFS;
+
+    return NULL;
+}
+
+const char *syslinux_check_bootsect(const void *bs, int *fs_type)
+{
+    uint8_t media_sig;
+    int sectorsize;
+    const struct fat_boot_sector *sectbuf = bs;
+    const char *retval;
+
+    media_sig = get_8(&sectbuf->bsMedia);
+    /* Must be 0xF0 or 0xF8-0xFF for FAT/NTFS volumes */
+    if (media_sig != 0xF0 && media_sig < 0xF8)
+	return "invalid media signature (not an FAT/NTFS volume?)";
+
+    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";
+
+    if (ntfs_check_zero_fields((struct ntfs_boot_sector *)bs))
+	retval = check_ntfs_bootsect(bs, fs_type);
+    else
+	retval = check_fat_bootsect(bs, fs_type);
+
+    return retval;
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/getopt/getopt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/getopt/getopt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/getopt/getopt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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 */
Index: bootcd/isolinux/syslinux-6.03/libinstaller/getopt/getopt_long.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/getopt/getopt_long.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/getopt/getopt_long.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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 '?';
+	}
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/linux/fiemap.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/linux/fiemap.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/linux/fiemap.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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 */
Index: bootcd/isolinux/syslinux-6.03/libinstaller/linux/loop.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/linux/loop.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/linux/loop.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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
Index: bootcd/isolinux/syslinux-6.03/libinstaller/linuxioctl.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/linuxioctl.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/linuxioctl.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,63 @@
+/*
+ * linuxioctl.h
+ *
+ * Wrapper for Linux ioctl definitions, including workarounds
+ */
+
+#ifndef LIBINSTALLER_LINUXIOCTL_H
+#define LIBINSTALLER_LINUXIOCTL_H
+
+#include <sys/ioctl.h>
+
+#ifdef __linux__
+
+#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_* */
+
+#undef SECTOR_SIZE		/* Defined in msdos_fs.h for no good reason */
+#undef SECTOR_BITS
+
+#ifndef FS_IOC_GETFLAGS
+/* Old kernel headers, these were once ext2-specific... */
+# include <linux/ext2_fs.h>	/* EXT2_IOC_* */
+
+# define FS_IOC_GETFLAGS EXT2_IOC_GETFLAGS
+# define FS_IOC_SETFLAGS EXT2_IOC_SETFLAGS
+
+# define FS_IMMUTABLE_FL EXT2_IMMUTABLE_FL
+
+#else
+
+# include <ext2fs/ext2_fs.h>
+
+#endif
+
+#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
+
+#ifndef  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 /* __linux__ */
+
+#endif /* LIBINSTALLER_LINUXIOCTL_H */
Index: bootcd/isolinux/syslinux-6.03/libinstaller/setadv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/setadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/setadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,168 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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"
+#include "syslxfs.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;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/setadv.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/setadv.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/setadv.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -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
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslinux.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslinux.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslinux.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,65 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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"
+
+#ifdef __CHECKER__
+# define _slimg __attribute__((noderef,address_space(1)))
+# define _force __attribute__((force))
+#else
+# define _slimg
+# define _force
+#endif
+
+/* 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 _slimg syslinux_ldlinux[];
+extern const unsigned int syslinux_ldlinux_len;
+extern const int syslinux_ldlinux_mtime;
+
+extern unsigned char _slimg syslinux_ldlinuxc32[];
+extern const unsigned int syslinux_ldlinuxc32_len;
+
+#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 *bs, int fs_type);
+
+/* Check to see that what we got was indeed an MS-DOS boot sector/superblock */
+const char *syslinux_check_bootsect(const void *bs, int *fs_type);
+
+/* 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
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxcom.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxcom.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxcom.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,305 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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"
+#include "syslxfs.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, FS_IOC_GETFLAGS, &flags)) {
+		flags &= ~FS_IMMUTABLE_FL;
+		ioctl(fd, FS_IOC_SETFLAGS, &flags);
+	    }
+	    break;
+	}
+	case VFAT:
+	{
+	    uint32_t attr = 0x00; /* Clear all attributes */
+	    ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
+	    break;
+	}
+    case NTFS:
+        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, FS_IOC_GETFLAGS, &flags)) {
+		flags |= FS_IMMUTABLE_FL;
+		ioctl(fd, FS_IOC_SETFLAGS, &flags);
+	    }
+	    break;
+	}
+	case VFAT:
+	{
+	    uint32_t attr = 0x07; /* Hidden+System+Readonly */
+	    ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
+	    break;
+	}
+    case NTFS:
+        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);
+}
+
+/*
+ * SYSLINUX installs the string 'SYSLINUX' at offset 3 in the boot
+ * sector; this is consistent with FAT filesystems.  Earlier versions
+ * would install the string "EXTLINUX" instead, handle both.
+ */
+int syslinux_already_installed(int dev_fd)
+{
+    char buffer[8];
+
+    xpread(dev_fd, buffer, 8, 3);
+    return !memcmp(buffer, "SYSLINUX", 8) || !memcmp(buffer, "EXTLINUX", 8);
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxcom.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxcom.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxcom.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,14 @@
+#ifndef _H_SYSLXCOM_
+#define _H_SYSLXCOM_
+
+#include "syslinux.h"
+
+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);
+int syslinux_already_installed(int dev_fd);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxfs.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxfs.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,29 @@
+/*
+ *   Copyright 2011-2012 Paulo Alcantara <pcacjr@zytor.com>
+ *
+ *   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 _SYSLXFS_H_
+#define _SYSLXFS_H_
+
+/* Global fs_type for handling fat, ntfs, ext2/3/4, btrfs, xfs and ufs1/2 */
+enum filesystem {
+    NONE,
+    EXT2,
+    BTRFS,
+    VFAT,
+    NTFS,
+    XFS,
+    UFS1,
+    UFS2,
+};
+
+extern int fs_type;
+
+#endif /* _SYSLXFS_H_ */
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxint.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxint.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,342 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2014 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
+ *
+ *   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
+
+#ifdef __GNUC__
+# ifdef __MINGW32__
+   /* gcc 4.7 miscompiles packed structures in MS-bitfield mode */
+#  define PACKED __attribute__((packed,gcc_struct))
+# else
+#  define PACKED __attribute__((packed))
+# endif
+#else
+# error "Need to define PACKED for this compiler"
+#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]) << 16);
+#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]) << 32);
+#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;
+    pp[1] = v >> 8;
+#endif
+}
+
+static inline void set_32(uint32_t *p, uint32_t v)
+{
+#if X86_MEM
+    /* Littleendian and unaligned-capable */
+    *p = v;
+#else
+    uint16_t *pp = (uint16_t *) p;
+    set_16(&pp[0], v);
+    set_16(&pp[1], v >> 16);
+#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__
+
+uint8_t get_8_sl(const uint8_t _slimg * p);
+uint16_t get_16_sl(const uint16_t _slimg * p);
+uint32_t get_32_sl(const uint32_t _slimg * p);
+uint64_t get_64_sl(const uint64_t _slimg * p);
+void set_8_sl(uint8_t _slimg * p, uint8_t v);
+void set_16_sl(uint16_t _slimg * p, uint16_t v);
+void set_32_sl(uint32_t _slimg * p, uint32_t v);
+void set_64_sl(uint64_t _slimg * p, uint64_t v);
+void memcpy_to_sl(void _slimg *dst, const void *src, size_t len);
+void memcpy_from_sl(void *dst, const void _slimg *src, size_t len);
+void memset_sl(void _slimg *dst, int c, size_t len);
+
+#else
+
+/* Sane system ... */
+static inline uint8_t get_8_sl(const uint8_t _slimg * p)
+{
+    return get_8((const uint8_t _force *)p);
+}
+static inline uint16_t get_16_sl(const uint16_t _slimg * p)
+{
+    return get_16((const uint16_t _force *)p);
+}
+static inline uint32_t get_32_sl(const uint32_t _slimg * p)
+{
+    return get_32((const uint32_t _force *)p);
+}
+static inline uint64_t get_64_sl(const uint64_t _slimg * p)
+{
+    return get_64((const uint64_t _force *)p);
+}
+static inline void set_8_sl(uint8_t _slimg * p, uint8_t v)
+{
+    set_8((uint8_t _force *)p, v);
+}
+static inline void set_16_sl(uint16_t _slimg * p, uint16_t v)
+{
+    set_16((uint16_t _force *)p, v);
+}
+static inline void set_32_sl(uint32_t _slimg * p, uint32_t v)
+{
+    set_32((uint32_t _force *)p, v);
+}
+static inline void set_64_sl(uint64_t _slimg * p, uint64_t v)
+{
+    set_64((uint64_t _force *)p, v);
+}
+static inline void memcpy_to_sl(void _slimg *dst, const void *src, size_t len)
+{
+    memcpy((void _force *)dst, src, len);
+}
+static inline void memcpy_from_sl(void *dst, const void _slimg *src, size_t len)
+{
+    memcpy(dst, (const void _force *)src, len);
+}
+static inline void memset_sl(void _slimg *dst, int c, size_t len)
+{
+    memset((void _force *)dst, c, len);
+}
+
+#endif
+
+#define LDLINUX_MAGIC	0x3eb202fe
+#define BS_MAGIC_VER	(0x1b << 9)
+
+/* 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;
+} PACKED;
+
+/* FAT bootsector format, also used by other disk-based derivatives */
+struct fat_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[442];
+	} 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[414];
+	} PACKED bs32;
+    } PACKED;
+
+    uint32_t bsMagic;
+    uint16_t bsForwardPtr;
+    uint16_t bsSignature;
+} PACKED;
+
+/* NTFS bootsector format */
+struct ntfs_boot_sector {
+    uint8_t bsJump[3];
+    char bsOemName[8];
+    uint16_t bsBytesPerSec;
+    uint8_t bsSecPerClust;
+    uint16_t bsResSectors;
+    uint8_t bsZeroed_0[3];
+    uint16_t bsZeroed_1;
+    uint8_t bsMedia;
+    uint16_t bsZeroed_2;
+    uint16_t bsUnused_0;
+    uint16_t bsUnused_1;
+    uint32_t bsUnused_2;
+    uint32_t bsZeroed_3;
+    uint32_t bsUnused_3;
+    uint64_t bsTotalSectors;
+    uint64_t bsMFTLogicalClustNr;
+    uint64_t bsMFTMirrLogicalClustNr;
+    uint8_t bsClustPerMFTrecord;
+    uint8_t bsUnused_4[3];
+    uint8_t bsClustPerIdxBuf;
+    uint8_t bsUnused_5[3];
+    uint64_t bsVolSerialNr;
+    uint32_t bsUnused_6;
+
+    uint8_t Code[420];
+
+    uint32_t bsMagic;
+    uint16_t bsForwardPtr;
+    uint16_t bsSignature;
+} PACKED;
+
+#define FAT_bsHead      bsJump
+#define FAT_bsHeadLen   offsetof(struct fat_boot_sector, bsBytesPerSec)
+#define FAT_bsCode	    bs32.Code	/* The common safe choice */
+#define FAT_bsCodeLen   (offsetof(struct fat_boot_sector, bsSignature) - \
+		     offsetof(struct fat_boot_sector, FAT_bsCode))
+
+#define NTFS_bsHead     bsJump
+#define NTFS_bsHeadLen  offsetof(struct ntfs_boot_sector, bsOemName)
+#define NTFS_bsCode     Code
+#define NTFS_bsCodeLen  (offsetof(struct ntfs_boot_sector, bsSignature) - \
+                            offsetof(struct ntfs_boot_sector, NTFS_bsCode))
+
+/* Check if there are specific zero fields in an NTFS boot sector */
+static inline int ntfs_check_zero_fields(const struct ntfs_boot_sector *sb)
+{
+    return !sb->bsResSectors && (!sb->bsZeroed_0[0] && !sb->bsZeroed_0[1] &&
+            !sb->bsZeroed_0[2]) && !sb->bsZeroed_1 && !sb->bsZeroed_2 &&
+            !sb->bsZeroed_3;
+}
+
+static inline int ntfs_check_sb_fields(const struct ntfs_boot_sector *sb)
+{
+    return ntfs_check_zero_fields(sb) &&
+            (!memcmp(sb->bsOemName, "NTFS    ", 8) ||
+             !memcmp(sb->bsOemName, "MSWIN4.0", 8) ||
+             !memcmp(sb->bsOemName, "MSWIN4.1", 8));
+}
+
+static inline int fat_check_sb_fields(const struct fat_boot_sector *sb)
+{
+    return sb->bsResSectors && sb->bsFATs &&
+            (!memcmp(sb->bs16.FileSysType, "FAT12   ", 8) ||
+             !memcmp(sb->bs16.FileSysType, "FAT16   ", 8) ||
+             !memcmp(sb->bs16.FileSysType, "FAT     ", 8) ||
+             !memcmp(sb->bs32.FileSysType, "FAT32   ", 8));
+}
+
+#endif /* SYSLXINT_H */
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxmod.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxmod.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxmod.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,208 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2014 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
+/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */
+#define _DEFAULT_SOURCE 1
+#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 _slimg *ex, int nptrs,
+			     const sector_t *sectp, int nsect)
+{
+    uint32_t addr = 0x8000;	/* ldlinux.sys starts loading here */
+    uint32_t base;
+    sector_t sect, lba;
+    unsigned int len;
+
+    base = addr;
+    len = lba = 0;
+
+    memset_sl(ex, 0, nptrs * sizeof *ex);
+
+    while (nsect) {
+	sect = *sectp++;
+
+	if (len) {
+	    uint32_t xbytes = (len + 1) * SECTOR_SIZE;
+
+	    if (sect == lba + len && xbytes < 65536 &&
+		((addr ^ (base + xbytes - 1)) & 0xffff0000) == 0) {
+		/* We can add to the current extent */
+		len++;
+		goto next;
+	    }
+
+	    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, const uint16_t _slimg *offset_p)
+{
+    return (char *)img + get_16_sl(offset_p);
+}
+static inline void _slimg *slptr(void _slimg *img,
+				 const uint16_t _slimg *offset_p)
+{
+    return (char _slimg *)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.
+ */
+int syslinux_patch(const sector_t *sectp, int nsectors,
+		   int stupid, int raid_mode,
+		   const char *subdir, const char *subvol)
+{
+    struct patch_area _slimg *patcharea;
+    struct ext_patch_area _slimg *epa;
+    struct syslinux_extent _slimg *ex;
+    const uint32_t _slimg *wp;
+    int nsect = ((boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT) + 2;
+    uint32_t csum;
+    int i, dw, nptrs;
+    struct fat_boot_sector *sbs = (struct fat_boot_sector *)boot_sector;
+    uint64_t _slimg *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 = (const uint32_t _slimg *)boot_image;
+	 get_32_sl(wp) != LDLINUX_MAGIC;
+	 wp++)
+	;
+    patcharea = (struct patch_area _slimg *)wp;
+    epa = slptr(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 = slptr(boot_image, &epa->secptroffset);
+    nptrs = get_16_sl(&epa->secptrcnt);
+
+#if 0
+    if (nsect > nptrs) {
+	/* Not necessarily an error in this case, but a general problem */
+	fprintf(stderr, "Insufficient extent space, build error!\n");
+	exit(1);
+    }
+#endif
+
+    /* -1 for the pointer in the boot sector, -2 for the two ADVs */
+    generate_extents(ex, nptrs, sectp, nsect-1-2);
+
+    /* ADV pointers */
+    advptrs = slptr(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(slptr(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(slptr(boot_image, &epa->subvoloffset), subvol, sublen);
+    }
+
+    /* Now produce a checksum */
+    set_32_sl(&patcharea->checksum, 0);
+
+    csum = LDLINUX_MAGIC;
+    for (i = 0, wp = (const uint32_t _slimg *)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;
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxopt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxopt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxopt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,275 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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 "syslxfs.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 */
+    {"device", 1, NULL, OPT_DEVICE},
+    {NULL, 0, NULL, 0}
+};
+
+const char short_options[] = "t:fid:UuzsS: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"
+	    "  --device         Force use of a specific block device (experts only)\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 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 due
+     * to limited output buffer size
+     */
+    fprintf(stderr,
+	    "  --menu-save= -M  Set the label to select as default on the next boot\n");
+    if (mode == MODE_SYSLINUX_DOSWIN)
+	fprintf(stderr,
+		"  --mbr        -m  Install an MBR\n"
+		"  --active     -a  Mark partition as active\n");
+
+    if (mode == MODE_SYSLINUX_DOSWIN || mode == MODE_SYSLINUX)
+	fprintf(stderr,
+		"  --force      -f  Ignore precautions\n");
+
+    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 OPT_DEVICE:
+	    if (mode != MODE_EXTLINUX)
+		usage(EX_USAGE, mode);
+	    opt.device = optarg;
+	    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;
+}
Index: bootcd/isolinux/syslinux-6.03/libinstaller/syslxopt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/libinstaller/syslxopt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/libinstaller/syslxopt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,44 @@
+#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,
+    OPT_DEVICE,
+};
+
+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
